为什么 compactMap return 没有结果?
Why does compactMap return a nil result?
考虑这个代码片段:
var a: String? = "abc"
var b: String?
let result = [a, b].compactMap { [=11=] }
执行后result
会
["abc"]
这是预期的结果。这里result(ElementOfResult
)的元素是String
.
print(type(of: result))
Array<String>
现在到了有趣的部分。将片段更改为
后
var a: String? = "abc"
var b: Int?
let result = [a, b].compactMap { [=14=] }
并执行它,result
将是
[Optional("abc"), nil]
这里result(ElementOfResult
)的元素是Any
,这是有道理的,因为Any
是String
和Int
的公分母。
print(type(of: result))
Array<Any>
为什么 compactMap
返回的 nil
结果与其定义相矛盾?
来自苹果的 compactMap
documentation
compactMap(_:)
Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.
Declaration
func compactMap(_ transform: (Self.Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
你在它的元素上创建一个 Any-array 和 compactMap 只给出 compactMap
Any-elements,没有 Optional<Any>
它可以考虑是否为 nil,所以所有元素都保留。
这是因为 [a, b]
被认为是 [Any]
。当数组文字中的元素类型完全不相关时(Int?
和 String?
),数组类型被推断为 [Any]
.
在传递给 compactMap
的闭包中,您 return 编辑了 [=19=]
,其类型为 Any
。这意味着 [=19=]
永远不可能是 nil
。当您将它们放入数组时,数组中的所有可选值都被包裹在 Any
中。因为你永远不会在闭包中 return a nil
,所以所有元素都保留在结果数组中。
编译器可以警告您关于在非可选中包装可选值 Any
s:
var a: String? = "abc"
let any: Any = a // warning!
但不幸的是,当您创建数组时它不会警告您。
无论如何,您可以通过指定您想要 [Any?]
:
来获得预期的行为
let result = ([a, b] as [Any?]).compactMap { [=11=] }
所以你可以从 Any
.
中解开它们
或者:
let result = [a as Any?, b as Any?].compactMap { [=12=] }
Why can an optional type be wrapped inside an Any
?
根据 docs(在 Any
和 AnyObject
的类型转换部分):
Any
can represent an instance of any type at all, including function types.
因此,Optional<T>
无疑可以表示为Any
。
考虑这个代码片段:
var a: String? = "abc"
var b: String?
let result = [a, b].compactMap { [=11=] }
执行后result
会
["abc"]
这是预期的结果。这里result(ElementOfResult
)的元素是String
.
print(type(of: result))
Array<String>
现在到了有趣的部分。将片段更改为
后var a: String? = "abc"
var b: Int?
let result = [a, b].compactMap { [=14=] }
并执行它,result
将是
[Optional("abc"), nil]
这里result(ElementOfResult
)的元素是Any
,这是有道理的,因为Any
是String
和Int
的公分母。
print(type(of: result))
Array<Any>
为什么 compactMap
返回的 nil
结果与其定义相矛盾?
来自苹果的 compactMap
documentation
compactMap(_:)
Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.
Declaration
func compactMap(_ transform: (Self.Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult]
你在它的元素上创建一个 Any-array 和 compactMap 只给出 compactMap
Any-elements,没有 Optional<Any>
它可以考虑是否为 nil,所以所有元素都保留。
这是因为 [a, b]
被认为是 [Any]
。当数组文字中的元素类型完全不相关时(Int?
和 String?
),数组类型被推断为 [Any]
.
在传递给 compactMap
的闭包中,您 return 编辑了 [=19=]
,其类型为 Any
。这意味着 [=19=]
永远不可能是 nil
。当您将它们放入数组时,数组中的所有可选值都被包裹在 Any
中。因为你永远不会在闭包中 return a nil
,所以所有元素都保留在结果数组中。
编译器可以警告您关于在非可选中包装可选值 Any
s:
var a: String? = "abc"
let any: Any = a // warning!
但不幸的是,当您创建数组时它不会警告您。
无论如何,您可以通过指定您想要 [Any?]
:
let result = ([a, b] as [Any?]).compactMap { [=11=] }
所以你可以从 Any
.
或者:
let result = [a as Any?, b as Any?].compactMap { [=12=] }
Why can an optional type be wrapped inside an
Any
?
根据 docs(在 Any
和 AnyObject
的类型转换部分):
Any
can represent an instance of any type at all, including function types.
因此,Optional<T>
无疑可以表示为Any
。