Swift:`["one": nil] as [String: Any]` 有效,为什么?

问题描述 投票:0回答:1
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,
ios swift nullable
1个回答
0
投票

每种类型都是

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"
]

(但如果可能的话,我还是会避免这种情况。)

© www.soinside.com 2019 - 2024. All rights reserved.