swift 可选值简介2

170 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情

if var and while var

使用var替代let,可以改变变量(值类型,不改变原来的类型)

let number = "1"
if var i = Int(number) {
   i += 1
   print(i)
} // 2
解包后可选值的作用域
func doStuff(withArray a: [Int]) {
  guard let firstElement = a.first else {
      return
  }
// firstElement 在这里已经被解包了
}

guard let 唯一的要求是必须离开当前的作用域,通常这意味着一条 return 语句,或抛出一个错误,亦或调用 fatalError (或者其他返回 Never 的方法)。如果你是在循环中使用 guard 的话,那么最后也可以是 break 或者 continue。

Never: 用于通知编译器它绝对不会返回。有俩类常见的函数会这么做:一种是像fatalError那样程序失败的函数,另一个像dispatchMain那样运行在整个程序生命周期的函数。编译器会使用这个信息来检查和确保控制流正确。举例来说,guard语句的else路径必须退出当前域或者调用一个不会返回的函数

Never又被叫做无人类型(uninhabited type)这种类型没有有效值,因此也不能被构建。在泛型环境里,把Never和Result结合在一起是非常有用的。例如,接受一个Result<A,E>(A,E都是泛型参数)的泛型API,你可以传入一个Result<..., Never>表示这个结果中永远都不会包含失败的情况,因为这种情况是构建不出来的。另外,一个声明为返回无人类型的函数也绝对不可能正常返回。

在Swift中,无人类型是通过一个不包含任意成员的enum实现的:

public enum Never {}

一般不会自定义返回Never的方法,除非你在为fatalError或者precondtionFailure写封装。一个很有意思的应用场景是,当你要创建一个很复杂的switch的语句,在case过程编译器会用空的case语句或者没有返回值轰炸你,而你又想集中处理某一个case语句的逻辑,这是放几个fatalError()就能编译器闭嘴。你还可以写一个unimplemented()方法,这样能够更好的表达这些调用是暂时没有实现的意思:

func unimplemented() -> Never {
    fatalError("This code path is not implemented yet")
}

Swift区分无,除了Never和nil, 还有Void,Void是空组(tuple)的另一种写法

public typealias Void = ()

Void或者()最常见的用法是作为那些不返回任何东西函数的返回值,不过也还有其它使用场景。举例来说,

在一个响应式编程框架中,使用Observable类型对事件进行建模,这里的T会提供事件中携带的内容类型。比如文本框发提供一个Observable,在每次用户编辑文本时发送事件,按钮类似,不过没有附加内容Observable<()>