Swift中的链接选项

时间:2015-11-16 21:26:46

标签: swift optional

到目前为止,我一直在Swift 2.1中解包Optionals:

@IBOutlet var commentTextView: UITextView!

if let comment = user["comment"] as? String {
    commentTextView.text = comment
}

我从未真正考虑过这个问题,但我认为我这样做的原因是因为我担心如果user["comment"]返回String以外的其他内容,这句话会引发错误:

commentTextView.text = user["comment"] as? String

如果user["comment"]不是String,是否会分配赋值运算符左侧的变量并抛出错误或者是否会跳过赋值?

3 个答案:

答案 0 :(得分:1)

我猜user实际上是字典[String: Any] if let comment = user["comment"] as? String { ... }做的事情不只是展开可选项而是展开conditional type casting (然后解开它的可选结果):

  

当您不确定向下转换是否成功时,请使用类型转换运算符(as?)的条件形式。这种形式的运算符将始终返回一个可选值,如果无法进行向下转换,则该值将为nil。这使您可以检查成功的向下转发。

现在,要回答您的问题,如果user["comment"]不是String,那么结果将是commentTextView.text将被分配nil值,这很糟糕因为它的类型是String!implicitly unwrapped optional),我们承诺它将永远nil。所以,是的,会有一个错误,实际上是一个例外,但不会出现在你想要它的地方,但是当你的应用程序试图访问它的值时,假设它不会是{{ 1}}。

你应该做什么取决于特定情况。

E.g。如果你可以让nil成为像user这样的字典,那么你就可以真正地解开选项并使用[String: String]之类的东西。或者,如果您完全确定if let comment = user["comment"] { ... }键的值总是,那么您可以"comment"

但如果那不可能,那么你必须坚持使用向下投射,而你唯一能做的就是使用它的强制形式,即let comment = user["comment"]!。如果commentTextView.text = user["comment"] as! String的值恰好不是"comment"而是其他值,那么这个至少会在现场产生例外。

答案 1 :(得分:0)

nil将被分配给变量。

如果变量的类型是非可选的,那么您将收到运行时错误。

但是,如果user["comment"] 一个String,您将收到有关丢失!?的编译错误。

答案 2 :(得分:0)

首先我们需要知道字典“user”是什么类型。

我认为它是[String:AnyObject]之类的未知类型,否则你为什么要尝试将它作为String展开。让我们写一个简短的测试来看看会发生什么:

let dict: [String: AnyObject] = ["SomeKey" : 1]
if let y = dict["SomeKey"] as? String {
    print(y)
}

您可以清楚地看到“SomeKey”的值是一个整数。尝试将其解包为String时不会触发错误,只会跳过“if”语句。如果实际发生的赋值很难证明(可能通过查看汇编代码),因为变量“y”在if语句之后根本不存在。我认为它根本不会被创建。

如果字典的类型被称为[String:String],您可以省略尝试将其作为String展开,因为它总是清楚该类型是String。

let dict2: [String: String] = ["SomeKey" : "SomeValue"]
if let y = dict2["WrongKey"] {
    // In this case print(y) will not be called because the subscript operator of the dictionary returns nil
    print(y)
}

// In this case print(y) will be called because the key is correct
if let y = dict2["SomeKey"] {
    print(y)
}