关闭

Swift 4.1的部分新特性(二)

在Xcode_9.3_beta_4的发布说明中,给出了一些新编译器所支持的Swfit变化。此文对其中两点进行说明:


Equatable和Hashable协议

对于Equatable协议所规定的==方法实现将会由编译器自动添加,只要类或者结构的所有存储属性都遵循Equatable协议,比如类型String, Int, Double, Array等(这些类型是模式遵循了Equatable协议的)。原来这样的代码:

struct Person:Equatable {
    var id:String

    static func ==(lhs: Person, rhs: Person) -> Bool {
        return lhs.id == rhs.id
    }
}

在Xcode9.3以后可以省略==方法,变为下面这样也是可以的:

struct Person:Equatable {
    var id:String
}

类似的,Hashable协议所要求的hashValue方法也会由编译器自动添加默认实现,同样需要所有存储属性都支持Hashable协议。当我们提供了自己的==hashValue方法时,它们将会覆盖编译器提供的默认版本。
得益于对Equatable协议更好的支持,现在包含可选类型元素的数组和字典也能直接比较了,只要它们的元素类型同样支持了Equatable协议。以下代码在Xcode9.2无法编译通过,但在9.3版本中已经可以了:

let arr1:[Int?]? = [1,2,3]
let arr2:[Int?]? = [1,2,3]
let isSame = arr1 == arr2  // isSame: true

隐式可选类型

目前把”隐式可选类型”传递给inout关键字修饰地”可选类型”参数是不允许的,比如:

func takesOptional(i: inout Int?) {
    //......
}

var x: Int! = 1
takesOptional(i: &x) //error: Cannot pass immutable value of type 'Int?' as inout argument

以上代码中,变量x是一个隐式可选类型,takesOptional方法要求的参数是一个可选类型,这在Xcode9.2中会报错。这符合我们对隐式可选类型的预期,因为它一旦初始化后就不可能为nil。但在Xcode9.3中这样做是允许的,这就存在以上代码中x重新变为nil的可能, 比如:

func takesOptional(i: inout Int?) {
    i = nil
}

var x: Int! = 1
takesOptional(i: &x)
print("x:\(x)")  // in Xcode9.3 beta4, output: x:nil

我个人猜想这与将来隐式可选类型可能被废除有关。

来评论一下吧!

您的邮箱地址不会被公开。 必填项已标记 *