me
me copied to clipboard
学习 MacOS 开发 (Part 22: Swift 语法细节)
version: 5.6
Trailing Closures
class Service {
init(handler: () -> Void) {
handler()
}
}
let p = Service {
print("hello world")
}
Shorthand Argument Names (SAN)
通过$0, $1 ... $n 代表函数参数
let add: (Int8, Int8) -> Int8 = { $0 + $1 }
print(add(1, 2))
let companies = ["bmw", "kfc", "ibm", "htc"]
// var uppercased = companies.map {
// (item: String) -> String in item.uppercased()
// }
let uppercased = companies.map { $0.uppercased() }
print(uppercased)
let
struct User {
var name: String?
}
let user = User(name: "nonocast")
user.name = "whatever" x Cannot assign to property: 'user' is a 'let' constant
print(user.name!)
struct是值类型,所以内部的var属性也一并不能修改。
class User {
var name: String?
}
let user = User()
user.name = "name1"
user.name = "name2"
print(user.name!)
class是引用类型,所以指针不能变,内容可以变。
if, guard, if-let, guard-let
if, guard, if-let, guard-let这是4个不同的逻辑。
- if, guard 检查后续statements的true/false
if
if true {
// statements
}
guard
guard true else {
// statements
// control statement: return, break, continue or throw.
}
guard let something = optional else {
// statements
// control statement: return, break, continue or throw.
}

- if-let, guard-let都会去尝试检查optional variable中的value, 如果有value返回true, 没有value返回false
Function with Multiple Parameters
func greet(person: String, alreadyGreeted: Bool) {
print("great \(person)")
}
greet(person: "nonocast", alreadyGreeted: true)
func greet(_ person: String, alreadyGreeted: Bool) {
print("great \(person)")
}
greet("nonocast", alreadyGreeted: true)
func greet(_ person: String, _ alreadyGreeted: Bool) {
print("great \(person)")
}
greet("nonocast", true)
func greet(_ person: String, already alreadyGreeted: Bool) {
print("great \(person)")
}
greet("nonocast", already: true)
Enumerations
enum CompassPoint {
case north
case south
case east
case west
}
func go(_ compass: CompassPoint) {
print(compass)
}
go(.north)
swift可以根据类型进行推测,
let x = CompassPoint.north
let y:CompassPoint = .north
if x == y, x == .north, y == .north {
print("x == y == .north")
}
Error Handling
enum LoginError: Error {
case userNotFound
case userLocked
case wrongPassword
}
func login() throws {
throw LoginError.userNotFound
}
do { try login() } catch { print(error) }
- func需要主动声明throws, 调用方必须要try
do {
try login()
} catch LoginError.userNotFound {
print("user not found")
} catch is LoginError {
print("error is LoginError")
} catch {
print(error)
}
- 只触发第一个满足条件的block
enum LoginError: Error {
case userNotFound
case userLocked
case wrongPassword
}
struct User {
var name: String?
}
func login() throws -> User {
throw LoginError.userNotFound
}
let user = try? login()
- 如果返回的是一个optional value,那么就可以通过try?简化do-try-catch操作
-
let user = try! login()
就是强制提取value,如果失败则会丢出一个runtime error