gpt4 book ai didi

swift - 为什么 compactMap 返回 nil 结果?

转载 作者:IT王子 更新时间:2023-10-29 05:36:59 28 4
gpt4 key购买 nike

考虑这个代码片段:

var a: String? = "abc"
var b: String?

let result = [a, b].compactMap { $0 }

执行后,result

["abc"]

这是预期的结果。这里result的元素(ElementOfResult)是String

print(type(of: result))
Array<String>

现在到了有趣的部分。将代码段更改为之后

var a: String? = "abc"
var b: Int?

let result = [a, b].compactMap { $0 }

并执行它,结果将是

[Optional("abc"), nil]

这里result (ElementOfResult) 的元素是Any 是有道理的,因为AnyString< 的公分母Int

print(type(of: result))
Array<Any>

为什么 compactMap 返回一个 nil 结果与其定义相矛盾?

来自 Apple 的 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]

最佳答案

这是因为[a, b]被认为是 [Any] .当数组文字中的元素类型完全不相关时(Int?String?),数组类型被推断为 [Any] .

在传递给 compactMap 的闭包中, 你返回了 $0 , 类型为 Any .这意味着 $0永远不可能是nil .数组中的所有可选值都包含在 Any 中你把它们放在数组中的那一刻。因为你永远不会返回 nil在闭包中,所有元素都保留在结果数组中。

编译器可以警告你关于在非可选中包装可选 Any小号:

var a: String? = "abc"

let any: Any = a // warning!

但不幸的是,当您创建数组时它不会警告您。

无论如何,您可以通过指定您想要 [Any?] 来获得预期的行为:

let result = ([a, b] as [Any?]).compactMap { $0 }

所以你可以从 Any 中解开它们.

或者:

let result = [a as Any?, b as Any?].compactMap { $0 }

Why can an optional type be wrapped inside an Any?

根据docs (在 AnyAnyObject 部分的类型转换中):

Any can represent an instance of any type at all, including function types.

因此,Optional<T>无疑可以用Any表示.

关于swift - 为什么 compactMap 返回 nil 结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51906624/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com