根据
SE-0054规则,只有在需要取消包装类型的情况下才会强制取消包装IUO。在您的情况下,IUO不需要被强制解包以被强制转换为
Any
(因为
Any
可以表示任何值),所以它没有被强制解包。
这种行为在以下问题和答案中进行了更详细的讨论:
您在字典中最终得到一个
ImplicitlyUnwrappedOptional
值是遗留行为,在最新的Swift快照中已经被删除,将来您将得到一个
Optional
值(因为IUO不再是一种类型)。
然而,这里需要注意的一点(我相信会让人们犯错)是,在4.1中IUO的打印方式已经改变了。
在Swift 4.0.3中,您的示例打印如下:
var aString: String! = "hello"
var params : [String : Any] = [
"myString" : aString
]
print(params)
// This prints ["myString": hello]
当强制将IUO转换为Any
时,会给你一种IUO被强制解包的假象。然而,这只是Swift 4.0.3中IUO的打印方式。如果它们有值,那么它们将打印该值,否则它们将打印nil
:
var aString: String! = nil
var params : [String : Any] = [
"myString" : aString
]
print(params)
// This prints ["myString": nil]
这种变化发生的原因是,Swift 4.1中删除了对ImplicitlyUnwrappedOptional类型实现Custom(Debug)StringConvertible协议的支持
在这个提交中,以便向移除该类型迈进。因此,现在使用Swift的默认打印机制(使用反射)来打印ImplicitlyUnwrappedOptional值。因此,在字典中,您将获得IUO的默认debugDescription,其外观如下:
let aString: String! = "hello"
let params : [String : Any] = [
"myString" : aString
]
print(params)
如果您单独打印它,您将获得其默认的description
,看起来像这样:
let aString: String! = "hello"
print(aString)
这是因为在Swift 4.1中,
ImplicitlyUnwrappedOptional
类型与
Optional
相同,都是一个带有两个选项的枚举。
public enum ImplicitlyUnwrappedOptional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
}
对于带有有效载荷值的隐式解包可选类型,Swift默认反射将其打印为包含封装值的
some
情况。但这只是暂时的;在Swift 4.1中,IUO类型目前已被弃用,但在Swift 4.2中将被移除。编译器在许多地方内部使用了IUO类型,需要
相当大的工作量来移除。因此,在4.2中,您的字典中将有
实际的 Optional
值,它们将打印为
Optional("hello")
。
[AnyHashable: Any]
类型的异构集合的形式明确指定String
和Int
的键和值。 - Tometoyou["myString": hello]
。没有出现这样的错误或警告。请参见此处。 - TheTigerAny
而不是Any?
会导致强制解包?另外,我正在使用 Swift 4.1,为什么它还没有被移除? - Tometoyou