Swift中可选和非可选函数参数之间的语义和最佳用例

时间:2014-08-16 23:53:36

标签: ios swift

我已经看到很多关于Swift中变量的讨论被声明为var a: String?var a: String!,前者是String类型的可选变量,后者是隐式解包的可选String。根据我的理解,当隐含地展开某些东西时,会假设已经包含在可选值中的值。为了使用语法a!.toInt(),必须进行外部检查,如下所示:

if a != nil {
   a!.toInt()
}

作为旁注,似乎更好的做法是将变量声明为可选类型,然后使用可选链接来解包该值(如果存在)。这样做的:

if let numberString = a?.toInt() {
    numberString.toInt()
}

是否存在访问像a!.toInt()之类的变量应该在实际应用中使用的场景?对我来说,似乎你要求运行时错误。

现在提出实际问题。我正在查看文档,特别是enumerateObjectsUsingBlock上的NSArray,并使用!声明了block参数。这是否意味着该函数的编写者假设块参数将是非零的?如果是这样,在该函数内部,语义之间的区别是什么:

func someMethodWithBlock(block:((String!)-> Void)!) {
     var a = "Hello"
     block.(a) //first syntax example
     block?.(a)//2nd
     block!.(a)//3rd
}

1 个答案:

答案 0 :(得分:2)

隐式解包Optionals在Cocoa API中几乎无处不在,因为它们被导入到Swift中 - 这是为了保持与Obj-C中普遍存在的指针语义的兼容性,而不需要!和{ {1}}遍布整个地方。这就是?方法的块采用NSArray参数的原因。

在Swift中,由于您指定的原因,常规的Optionals(String!等)很可取:它们不容易出错。隐式解包的选项主要用于仅在某些情况下使用,例如在您需要pass self to a function before initialization is complete时。 (如果你知道一个变量不是nil,那就像Int?一样展开就好了.IUO的危险在于它会写成a!.toInt(),对于读者而言,这看起来是完全安全的它不是。)