Swift中[String: Any?]转[String: Any]兼容nil的原因解析
为什么
[String: Any?]能转成[String: Any]传参,直接声明却不行? 先看代码示例:
可正常运行的代码
func logEvent(events: [String: Any]) { print(events); } let eventProperties: [String: Any?] = [ "one": nil, "two": "2" ] logEvent(events: eventProperties as [String: Any])
直接声明会报错的代码
let eventProperties: [String: Any] = [ "one": nil, // 错误提示:'nil' is not compatible with expected dictionary value type 'Any' "two": "2" ]
核心原因拆解
Any不接受裸nil,但能容纳可选类型实例Any可以表示任意类型的实例,但nil本身不是实例——它是可选类型的“无值”状态。而Any?是Optional<Any>的语法糖,它本身是合法的Swift类型,所以Optional<Any>的实例(不管是.some(值)还是.none)都可以被Any容纳。类型转换的本质是把
Any?实例当作Any存储
当你把[String: Any?]转成[String: Any]时,字典里的每个元素其实是把Optional<Any>类型的对象直接存进了Any的位置:"two": "2"对应的是Optional<Any>.some("2"),这个可选包装本身就是Any能接受的实例;"one": nil对应的是Optional<Any>.none,这个“无值”的可选实例同样是Any能接受的对象。
直接赋值裸nil时编译器找不到类型上下文
直接给[String: Any]的字典写nil,编译器不知道你要的是哪种可选类型的nil(比如String?还是Int?),而Any又不能直接接受无类型的裸nil,所以直接报错。
内容的提问来源于stack exchange,提问作者TpoM6oH
相关产品推荐
相关产品推荐

