Swift 为什么compactMap返回零结果?

Swift 为什么compactMap返回零结果?,swift,swift4.1,Swift,Swift4.1,考虑以下代码片段: var a: String? = "abc" var b: String? let result = [a, b].compactMap { $0 } 执行后,结果 ["abc"] [Optional("abc"), nil] 这是预期的结果。这里的result元素(ElementOfResult)是String print(type(of: result)) Array<String> 然后执行它,结果将 ["abc"] [Optional("abc

考虑以下代码片段:

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

let result = [a, b].compactMap { $0 }
执行后,
结果

["abc"]
[Optional("abc"), nil]
这是预期的结果。这里的result元素(
ElementOfResult
)是
String

print(type(of: result))
Array<String>
然后执行它,
结果将

["abc"]
[Optional("abc"), nil]
这里的结果元素(
ElementOfResult
)是有意义的
Any
,因为
Any
String
Int
的公分母

print(type(of: result))
Array<Any>
打印(类型(类型:结果))
排列

压缩映射(389;:) 返回一个数组,其中包含使用此序列的每个元素调用给定转换的非nil结果

宣言 func compactMap(uTransform:(Self.Element)throws->ElementOfResult?)rethrows->[ElementOfResult]


您创建一个任意数组,其元素上的compactMap只提供
compactMap
任何元素,没有
可选的
,它可以认为是零或不是零,所以所有元素都保留。

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

在传递给
compactMap
的闭包中,您返回了
$0
,它的类型为
Any
。这意味着
$0
永远不能是
nil
。当您将数组中的所有选项放入数组时,它们都被包装在一个
Any
中。因为在闭包中从不返回
nil
,所以所有元素都保留在结果数组中

编译器可以警告您在非可选
Any
s中包装选项:

var a: String? = "abc"

let any: Any = a // warning!
但不幸的是,当您创建数组时,它不会发出警告

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

let result = ([a, b] as [Any?]).compactMap { $0 }
所以你可以从
任何
中打开它们

或:

为什么可选类型可以包装在
Any

根据(在
Any
AnyObject
部分的类型转换中):

Any
可以表示任何类型的实例,包括函数类型


因此,
可选
无疑可以用
任何
来表示

更令人费解的是为什么
结果
的类型是
[Any]
。我希望它是
[Any?]
@user1046037
compactMap
可以删除nil。如果
compactMap
已经确定它们中没有一个是nil,那么返回[Any]有什么意义呢?基于最初的示例,我们想知道为什么结果可以是
[Any]
类型,并且仍然保持
nil
@user1046037,因为任何东西都是
Any
Any
可以保存每种类型。下面的代码抛出一个编译错误,
让x:Any=nil
@user1046037
nil
不在结果数组中,而是一个可选的nil,它只打印
nil
。我的错,Any可以是nil,
var y:Int?=无设x:Any=y为Any