var myVariable =42 myVariable =50 let myConstant =42
可以显式声明变量类型,若没有则隐式推断,类似下面的Double
1 2 3
let implicitInteger =70 let implicitDouble =70.0 let explicitDouble: Double=70
赋值同一类型
1 2 3 4 5
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)
字符串中通过\(变量)的方法得到变量的字符串表示
1 2 3 4
let apples =3 let oranges =5 let appleSummary ="I have \(apples) apples." let fruitSummary ="I have \(apples + oranges) pieces of fruit."
多行文本的写法
1 2 3 4 5 6 7 8 9
// """ """ 包含的内容 let quotation =""" Even though there's whitespace to the left, the actual lines aren't indented. Except for this line. Double quotes (") can appear without being escaped. I still have \(apples + oranges) pieces of fruit. """
数组/字典通过 [] 遍历
1 2 3 4 5 6 7 8 9
var fruits = ["strawberries", "limes", "tangerines"] fruits[1] ="grapes"
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.") caselet 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编译错误,这是编程的实践,避免开发者遗漏
未使用的变量_
1 2 3 4 5 6 7 8 9 10 11 12 13 14
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,用_可以告诉编译器这件事方便优化
1 2
// 如果非要定义了不用,会给一个警告 Immutable value 'key' was never used; consider replacing with '_' or removing it
overridefuncsimpleDescription() -> String { return"A square with sides of length \(sideLength)." } } let test =Square(sideLength: 5.2, name: "my test square") test.area() test.simpleDescription()
enumRank: Int { case ace =1 case two, three, four, five, six, seven, eight, nine, ten case jack, queen, king
funcsimpleDescription() -> String { switchself { case .ace: return"ace" case .jack: return"jack" case .queen: return"queen" case .king: return"king" default: returnString(self.rawValue) } } } let ace =Rank.ace let aceRawValue = ace.rawValue
rawValue 默认0开始,然后递增
枚举的 case 值是实际值,而不仅仅是编写其原始值的另一种方式。事实上,在没有有意义的原始值的情况下,可以不必提供原始值。
funcsimpleDescription() -> String { switchself { case .spades: return"spades" case .hearts: return"hearts" case .diamonds: return"diamonds" case .clubs: return"clubs" } } } let hearts =Suit.hearts let heartsDescription = hearts.simpleDescription()
funcconnectUser(toserver: String) async { // 异步调用 asynclet userID = fetchUserID(from: server) asynclet username = fetchUsername(from: server) // 等待返回后执行下一句 let greeting =await"Hello \(username), user ID \(userID)" print(greeting) }
Task { await connectUser(to: "primary2") }
等待任务组
1 2 3 4 5 6 7 8 9 10 11 12 13 14
let userIDs =await withTaskGroup(of: Int.self) { group in for server in ["primary", "secondary", "development"] { group.addTask { returnawait fetchUserID(from: server) } }
var results: [Int] = [] forawait result in group { results.append(result) } return results }
协议与扩展
使用关键字Protocol定义协议
1 2 3 4
protocolExampleProtocol { var simpleDescription: String { get } mutatingfuncadjust() }
classSimpleClass: ExampleProtocol { var simpleDescription: String="A very simple class." var anotherProperty: Int=69105 funcadjust() { simpleDescription +=" Now 100% adjusted." } } var a =SimpleClass() a.adjust() let aDescription = a.simpleDescription
structSimpleStructure: ExampleProtocol { var simpleDescription: String="A simple structure" mutatingfuncadjust() { simpleDescription +=" (adjusted)" } } var b =SimpleStructure() b.adjust() let bDescription = b.simpleDescription
结构体的adjust方法前有mutating修饰用于修改结构体的成员
可以使用扩展来为已有的类型添加方法
1 2 3 4 5 6 7 8 9 10
extensionInt: ExampleProtocol { var simpleDescription: String { return"The number \(self)" } mutatingfuncadjust() { self+=42 } } print(7.simpleDescription) // Prints "The number 7"
异常捕获
通过实现Error协议来表示错误类型
1 2 3 4 5
enumPrinterError: Error { case outOfPaper case noToner case onFire }
throws 关键字来抛出异常
1 2 3 4 5 6
funcsend(job: Int, toPrinterprinterName: String) throws -> String { if printerName =="Never Has Toner" { throwPrinterError.noToner } return"Job sent" }
可以使用 do-catch 来捕获异常,try 修饰可能会抛出异常的代码
1 2 3 4 5 6 7
do { let printerResponse =try send(job: 1040, toPrinter: "Bi Sheng") print(printerResponse) } catch { print(error) } // Prints "Job sent"
多种异常的处理
1 2 3 4 5 6 7 8 9 10 11
do { let printerResponse =try send(job: 1440, toPrinter: "Gutenberg") print(printerResponse) } catchPrinterError.onFire { print("I'll just put this over here, with the rest of the fire.") } catchlet printerError asPrinterError { print("Printer error: \(printerError).") } catch { print(error) } // Prints "Job sent"