高端网站官网,企业官方网站是什么,网站设计与制作专业,省品牌建设联合会网站获取版本号
swift -versionHello world
print(Hello, world!)末尾不需要分号
值
常量(let),变量(var)
var myVariable 42
myVariable 50
let myConstant 42可以显式声明变量类型,若没有则隐式推断,类似下面的Double
let implicitInteger 70
let implicit…获取版本号
swift -versionHello world
print(Hello, world!)末尾不需要分号
值
常量(let),变量(var)
var myVariable 42
myVariable 50
let myConstant 42可以显式声明变量类型,若没有则隐式推断,类似下面的Double
let implicitInteger 70
let implicitDouble 70.0
let explicitDouble: Double 70赋值同一类型
let label The width is
let width 94
// 去掉String报错
// Binary operator cannot be applied to operands of type String and Int
let widthLabel label String(width)字符串中通过\(变量名)的方法得到变量的字符串表示
let apples 3
let oranges 5
let appleSummary I have \(apples) apples.
let fruitSummary I have \(apples oranges) pieces of fruit.多行文本的写法
// 包含的内容
let quotation Even though theres whitespace to the left,the actual lines arent indented.Except for this line.Double quotes () can appear without being escaped.I still have \(apples oranges) pieces of fruit.数组/字典通过 [] 遍历
var fruits [strawberries, limes, tangerines]
fruits[1] grapesvar occupations [Malcolm: Captain,Kaylee: Mechanic,]
occupations[Jayne] Public Relations自动扩容
fruits.append(blueberries)
print(fruits)空数组/字典
fruits []
occupations [:]// 指定类型
let emptyArray: [String] []
let emptyDictionary: [String: Float] [:]控制流
循环: for-in,while,repeat-while 条件: if
let individualScores [75, 43, 103, 87, 12]
var teamScore 0
for score in individualScores {if score 50 {teamScore 3} else {teamScore 1}
}
print(teamScore)
// Prints 11
if 赋值
let scoreDecoration if teamScore 10 {
} else {
}
print(Score:, teamScore, scoreDecoration)属于语法糖,少写一个赋值
var n 2
while n 100 {n * 2
}
print(n)
// Prints 128var m 2
// 这个其它语言中一般是用do, 用repeat可能是为了强调循环?
repeat {m * 2
} while m 100
print(m)
// Prints 128var total 0
for i in 0..4 {total i
}
print(total)
// Prints 6for i in 0..4, i的遍历区间是0,1,2,3
可选型(optional)
类型后面跟问号if let name optionalName 会解包,能确定name是nil还是有具体的值
var optionalString: String? Hello
print(optionalString nil)
// Prints falsevar optionalName: String? John Appleseed
var greeting Hello!
if let name optionalName {greeting Hello, \(name)print(greeting)
}还有种处理可选型的方法是通过??
let nickname: String? nil
let fullName: String John Appleseed
let informalGreeting Hi \(nickname ?? fullName)nickname 有值则用nickname的值,没有值则用??后的值。这是种默认值的写法,更健壮的处理当数据可能为nil的情况。
switch 的写法
let vegetable red pepper
switch vegetable {
case celery:print(Add some raisins and make ants on a log.)
case cucumber, watercress:print(That would make a good tea sandwich.)
case let x where x.hasSuffix(pepper):print(Is it a spicy \(x)?)
default:print(Everything tastes good in soup.)
}
// Prints Is it a spicy red pepper?case类型可以是String这点比Objective-C方便很多编程语言是给人读的。
去掉default语句会报Switch must be exhaustive编译错误,这是编程的实践避免开发者遗漏
未使用的变量_
let interestingNumbers [Prime: [2, 3, 5, 7, 11, 13],Fibonacci: [1, 1, 2, 3, 5, 8],Square: [1, 4, 9, 16, 25],
]
var largest 0
for (_, numbers) in interestingNumbers {for number in numbers {if number largest {largest number}}
}
print(largest)访问for循环时没有使用到字典的key,用_可以告诉编译器这件事方便优化
// 如果非要定义了不用,会给一个警告
Immutable value key was never used; consider replacing with _ or removing it函数和闭包
函数关键字 func- 后跟返回值函数定义对参数的声明和objective-c类似
func greet(person: String, day: String) - String {return Hello \(person), today is \(day).
}
greet(person: Bob, day: Tuesday)通过元组(tuple)可以处理多个值
func calculateStatistics(scores: [Int]) - (min: Int, max: Int, sum: Int) {var min scores[0]var max scores[0]var sum 0for score in scores {if score max {max score} else if score min {min score}sum score}return (min, max, sum)
}
let statistics calculateStatistics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)
// Prints 120
print(statistics.2)
// Prints 120嵌套函数
func returnFifteen() - Int {var y 10func add() {y 5}add()return y
}
returnFifteen()这个见的少,只见过类似概念的Java里的内部类
函数作返回值参数 Functions are a first-class type. This means that a function can return another function as its value. 类型规定了变量可以取的值得范围以及该类型的值可以进行的操作。根据类型的值的可赋值状况可以把类型分为三类 1、一级的first class。该等级类型的值可以传给子程序作为参数可以从子程序里返回可以赋给变量。大多数程序设计语言里整型、字符类型等简单类型都是一级的。 2、二级的second class。该等级类型的值可以传给子程序作为参数但是不能从子程序里返回也不能赋给变量。 3、三级的third class。该等级类型的值连作为参数传递也不行。 函数当返回值
func makeIncrementer() - ((Int) - Int) {func addOne(number: Int) - Int {return 1 number}return addOne
}
var increment makeIncrementer()
increment(7)函数当参数
func hasAnyMatches(list: [Int], condition: (Int) - Bool) - Bool {for item in list {if condition(item) {return true}}return false
}
func lessThanTen(number: Int) - Bool {return number 10
}
var numbers [20, 19, 7, 12]
// lessThanTen 函数作为参数
hasAnyMatches(list: numbers, condition: lessThanTen)闭包
函数是一种特殊的闭包有名字的闭包(closures)
// {} 内的是闭包
numbers.map({ (number: Int) - Int inlet result 3 * numberreturn result
})简化闭包写法
省略return
let mappedNumbers numbers.map({ number in 3 * number })
print(mappedNumbers)当闭包是函数的唯一参数时可以完全省略括号
let sortedNumbers numbers.sorted { $0 $1 }
print(sortedNumbers)对象和类
class Shape {var numberOfSides 0func simpleDescription() - String {return A shape with \(numberOfSides) sides.}
}创建对象
var shape Shape()
shape.numberOfSides 7
var shapeDescription shape.simpleDescription()初始化函数
class NamedShape {var numberOfSides: Int 0var name: Stringinit(name: String) {self.name name}func simpleDescription() - String {return A shape with \(numberOfSides) sides.}
}子类重写父类方法
class Square: NamedShape {var sideLength: Doubleinit(sideLength: Double, name: String) {self.sideLength sideLengthsuper.init(name: name)numberOfSides 4}func area() - Double {return sideLength * sideLength}override func simpleDescription() - String {return A square with sides of length \(sideLength).}
}
let test Square(sideLength: 5.2, name: my test square)
test.area()
test.simpleDescription()属性访问器getter setter
class EquilateralTriangle: NamedShape {var sideLength: Double 0.0init(sideLength: Double, name: String) {self.sideLength sideLengthsuper.init(name: name)numberOfSides 3}var perimeter: Double {get {return 3.0 * sideLength}set {sideLength newValue / 3.0}}override func simpleDescription() - String {return An equilateral triangle with sides of length \(sideLength).}
}
var triangle EquilateralTriangle(sideLength: 3.1, name: a triangle)
print(triangle.perimeter)
// Prints 9.3
triangle.perimeter 9.9
print(triangle.sideLength)
// Prints 3.3000000000000003计算属性
class TriangleAndSquare {var triangle: EquilateralTriangle {willSet {square.sideLength newValue.sideLength}}var square: Square {willSet {triangle.sideLength newValue.sideLength}}init(size: Double, name: String) {square Square(sideLength: size, name: name)triangle EquilateralTriangle(sideLength: size, name: name)}
}
var triangleAndSquare TriangleAndSquare(size: 10, name: another test shape)
print(triangleAndSquare.square.sideLength)
// Prints 10.0
print(triangleAndSquare.triangle.sideLength)
// Prints 10.0
triangleAndSquare.square Square(sideLength: 50, name: larger square)
print(triangleAndSquare.triangle.sideLength)
// Prints 50.0枚举和结构体
enum Rank: Int {case ace 1case two, three, four, five, six, seven, eight, nine, tencase jack, queen, kingfunc simpleDescription() - String {switch self {case .ace:return acecase .jack:return jackcase .queen:return queencase .king:return kingdefault:return String(self.rawValue)}}
}
let ace Rank.ace
let aceRawValue ace.rawValuerawValue 默认0开始然后递增
枚举的 case 值是实际值而不仅仅是编写其原始值的另一种方式。事实上在没有有意义的原始值的情况下可以不必提供原始值。
enum Suit {case spades, hearts, diamonds, clubsfunc simpleDescription() - String {switch self {case .spades:return spadescase .hearts:return heartscase .diamonds:return diamondscase .clubs:return clubs}}
}
let hearts Suit.hearts
let heartsDescription hearts.simpleDescription()
并发
异步方法的关键字 async调用异步方法前面加await
func fetchUserID(from server: String) async - Int {print(fetchUserID)if server primary {return 97}return 501
}func fetchUsername(from server: String) async - String {print(fetchUsername)let userID await fetchUserID(from: server)if userID 501 {return John Appleseed}return Guest
}func connectUser(to server: String) async {// 异步调用async let userID fetchUserID(from: server)async let username fetchUsername(from: server)// 等待返回后执行下一句let greeting await Hello \(username), user ID \(userID)print(greeting)
}Task {await connectUser(to: primary2)
}等待任务组
let userIDs await withTaskGroup(of: Int.self) { group infor server in [primary, secondary, development] {group.addTask {return await fetchUserID(from: server)}}var results: [Int] []for await result in group {results.append(result)}return results
}协议与扩展
使用关键字Protocol定义协议
protocol ExampleProtocol {var simpleDescription: String { get }mutating func adjust()
}类,枚举和结构体都可以实现协议
class SimpleClass: ExampleProtocol {var simpleDescription: String A very simple class.var anotherProperty: Int 69105func adjust() {simpleDescription Now 100% adjusted.}
}
var a SimpleClass()
a.adjust()
let aDescription a.simpleDescriptionstruct SimpleStructure: ExampleProtocol {var simpleDescription: String A simple structuremutating func adjust() {simpleDescription (adjusted)}
}
var b SimpleStructure()
b.adjust()
let bDescription b.simpleDescription结构体的adjust方法前有mutating修饰用于修改结构体的成员
可以使用扩展来为已有的类型添加方法
extension Int: ExampleProtocol {var simpleDescription: String {return The number \(self)}mutating func adjust() {self 42}}
print(7.simpleDescription)
// Prints The number 7异常捕获
通过实现Error协议来表示错误类型
enum PrinterError: Error {case outOfPapercase noTonercase onFire
}throws 关键字来抛出异常
func send(job: Int, toPrinter printerName: String) throws - String {if printerName Never Has Toner {throw PrinterError.noToner}return Job sent
}可以使用 do-catch 来捕获异常try 修饰可能会抛出异常的代码
do {let printerResponse try send(job: 1040, toPrinter: Bi Sheng)print(printerResponse)
} catch {print(error)
}
// Prints Job sent多种异常的处理
do {let printerResponse try send(job: 1440, toPrinter: Gutenberg)print(printerResponse)
} catch PrinterError.onFire {print(Ill just put this over here, with the rest of the fire.)
} catch let printerError as PrinterError {print(Printer error: \(printerError).)
} catch {print(error)
}
// Prints Job sentdefer关键词修饰的代码会在函数所有代码执行完成后函数return返回前执行。 无论代码是否抛出异常都会执行。它一般用于建立或清理代码。
有点类似finally 部分,可以避免异常的时候没释放内存。这在某个函数有多个返回出口的时候特别有用。
var fridgeIsOpen false
let fridgeContent [milk, eggs, leftovers]func fridgeContains(_ food: String) - Bool {fridgeIsOpen truedefer {fridgeIsOpen false}let result fridgeContent.contains(food)return result
}
if fridgeContains(banana) {print(Found a banana)
}
print(fridgeIsOpen)泛型
泛型: 类型
func makeArrayItem(repeating item: Item, numberOfTimes: Int) - [Item] {var result: [Item] []for _ in 0..numberOfTimes {result.append(item)}return result
}
makeArray(repeating: knock, numberOfTimes: 4)可以对方法函数类枚举结构体应用泛型
// where T.Element: Equatable , T.Element U.Element表示只有元素遵循 Equatable 协议且内部的类型一致时才可以使用anyCommonElements方法
func anyCommonElementsT: Sequence, U: Sequence(_ lhs: T, _ rhs: U) - Boolwhere T.Element: Equatable, T.Element U.Element
{for lhsItem in lhs {for rhsItem in rhs {if lhsItem rhsItem {return true}}}return false
}
anyCommonElements([1, 2, 3], [3])参考
Swift-Doc什么是 First-class functionSwift系列之关于Swift defer的正确使用Swift限定泛型、协议扩展或约束的where