me icon indicating copy to clipboard operation
me copied to clipboard

学习 MacOS 开发 (Part 22: Swift 语法细节)

Open nonocast opened this issue 2 years ago • 0 comments

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.
}
Screen Shot 2022-05-09 at 23 51 32
  • 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

nonocast avatar May 08 '22 15:05 nonocast