我正在使用 Swift,在数组上使用 contains 方法时遇到问题。以下代码运行正常:
let result = ["hello", "world"].contains(Optional("hello")) // ✅ Works fine
但是,当我尝试对在单独的常量(或变量)中声明的数组使用相同的 contains 方法时,出现编译时错误:
let stringArray = ["hello", "world"]
let result = stringArray.contains(Optional("hello")) // ❌ Compile-time error
编译器生成以下错误消息:
Cannot convert value of type 'Optional<String>' to expected argument type 'String'
这两个例子在概念上似乎相似,但第二个例子导致编译时错误,而第一个例子运行良好。
这让我很困惑,因为我知道 Swift 在将非可选值与可选值进行比较时会自动将非可选值提升为可选值。这意味着“hello”应该被隐式转换为 Optional(“hello”) 以进行比较。(🔗 参考)
我目前的理解是:
contains(_:) 方法定义如下:
func contains(_ element: Self.Element) -> Bool
在内部,它调用
contains(where:)
,如 Swift 源代码所示:contains(where:)
采用应用运算符的闭包==
来进行比较。由于 Swift 允许直接比较
String
和String?
(与可选项进行比较时String
隐式提升为),我希望以相同的方式工作。String?
contains(where:)
我的问题:
- 为什么第一个例子可以运行,而第二个例子却出现编译时错误?
- 尽管两种情况都涉及将可选值与非可选值进行比较,但究竟是什么导致了第二种情况下出现此错误?
contains(_:)
使用显式数组变量而不是直接数组字面量时,行为是否有所不同?如果是,为什么?
我知道有不同的方法可以解决这个问题,比如使用零合并或可选绑定,但我真正寻找的是为什么这个问题在编译时级别发生的详细解释。
有人能解释这种行为的根本原因吗?