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?]
更改为 let eventProperties: [String: Any]
我会得到有意义的错误。但为什么上面的代码有效?
'nil' is not compatible with expected dictionary value type 'Any'
"one": nil,
每种类型都是
Any
的子类型。这包括Any?
。所以你绝对可以将 [String: Any?]
转换为 [String: Any]
因为 Any?
是一种 Any
.
另一方面,文字
nil
只适用于Optional
,所以let x: Any = nil
是无效的。 Any
不是Optional
.
这个烂摊子是你应该避免
Any
的一个关键原因,你应该强烈避免Any?
。当与 Optional-promotion 结合使用时(一个类型在分配时可以提升为 Optional 本身的事实),Any-types 很快就会变成一堆令人困惑的错误和微妙的行为。一个非常常见的问题是最终得到像 Any??
这样的 .some(nil)
值,它本身不是 nil。尽可能避免这种情况。
对于您的日志记录问题,
[String: Any]
可能没问题。我自己使用它非常有效。但是不要创建 [String: Any?]
字典。如果你真的需要一个你可以包含的 nil 占位符,那么这样做:
let anyNil = Any?.none as Any
let eventProperties: [String: Any] = [
"one": anyNil,
"two": "2"
]
(但如果可能的话,我还是会避免这种情况。)