【发布时间】:2014-08-05 02:13:13
【问题描述】:
我一直在玩 Swift,发现当向下转换要插入字典的对象时,我收到一个奇怪的警告:Treating a forced downcast to 'String' as optional will never produce 'nil'。如果我用as? 替换as,那么警告就会消失。
func test() -> AnyObject! {
return "Hi!"
}
var dict = Dictionary<String,String>()
dict["test"]=test() as String
Apple 的文档说明如下
因为向下转换可能会失败,所以类型转换运算符有两种不同的形式。可选形式
as?返回您尝试向下转换为的类型的可选值。强制形式as尝试向下转换并将结果强制展开为单个复合动作。
我不清楚为什么在这里使用as? 而不是as 是正确的。一些测试表明,如果我将 test() 更改为返回 Int 而不是 String,如果我继续使用 as,代码将退出并出现错误。如果我切换到使用as?,那么代码将继续正常执行并跳过该语句(dict 将保持为空)。但是,我不确定为什么这是可取的。在我看来,我宁愿程序出现错误退出并让我知道强制转换不成功,然后简单地忽略错误语句并继续执行。
根据文档,我应该使用强制形式“仅当您确定向下转换将始终成功时”。在这种情况下,我确信向下转换总是会成功,因为我知道test() 只能返回一个字符串,所以我认为这是强制向下转换形式的完美情况。那么为什么编译器会给我一个警告呢?
【问题讨论】:
-
首先,有很多 Cocoa 类型桥接,因为没有
import Foundation,它甚至无法编译,因为String不是类类型并且与@ 不兼容987654334@。如果您将最后一个String更改为NSString,警告就会消失,这意味着您在as中使用非类类型String可能是个问题。 -
@newacct 有趣的是,如果在 Dictionary 定义或向下转换中将 String 替换为 NSString,警告就会消失。但是,如果在 both 位置将 String 替换为 NSString,警告仍然存在。
-
注意:自 Swift 2 以来,
as的许多功能已被删除,并被as!取代。所以当你使用as!时你会得到同样的错误(使用as不会再产生这个错误了)
标签: swift optional downcast forced-unwrapping