我已经看到很多关于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
}
答案 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()
,对于读者而言,这看起来是完全安全的它不是。)