为什么当我导入 Foundation 时 String.contains 的行为有所不同?

min*_*wei 9 string foundation swift

刚开始学习 Swift,我对以下行为感到非常困惑。

这是我在没有 Foundation 的情况下运行 String.contains 时得到的结果:

"".contains("") // true
"a".contains("") // true
"a".contains("a") // true
"" == "" // true
Run Code Online (Sandbox Code Playgroud)

这就是我从基金会得到的:

import Foundation

"".contains("") // false
"a".contains("") // false
"a".contains("a") // true
"" == "" // true
Run Code Online (Sandbox Code Playgroud)

为什么根据是否导入 Foundation,结果会有所不同?是否还有其他此类差异,是否有详尽的列表?在基金会文档中没有找到任何内容,但这似乎对文档很重要。我只知道另一个例子。

另:这是怎么发生的,正常吗?我知道 Swift 具有诸如扩展之类的东西,一旦包含某些东西,它们就会改变每个实例的行为,但肯定这只会添加行为,而不是改变现有的行为。如果现有的行为被改变,语言不应该以某种方式表明这一点,比如如果我想要不同的行为,就让我使用不同的类型?

mat*_*att 11

基本上这和我在这里回答的问题是一样的。

\n

Foundation 不是 Swift 的一部分,它是 Cocoa 的一部分,Cocoa 是一个较旧的 Objective-C 库,比 Swift 早很多很多年。Foundation 的字符串版本是 NSString。但是 Swift String 是“桥接到”NSString 的,所以一旦你导入 Foundation,一堆 NSString 方法就会像 Swift String 的一部分一样活跃起来,尽管它们不是。在你的例子中,你实际上最终调用了一个完全不同的方法,正如你所发现的,它给出了不同的结果。

\n

contains查看此内容的一个好方法是按住 Command 键并单击代码中的术语(或者更好的是,按住 Option 键并单击它,然后单击“在开发人员文档中打开”):

\n
    \n
  • 如果您尚未导入 Foundation(或 UIKit),则跳转到 Swift String\'s contains
  • \n
  • 如果你已经导入了 Foundation,你会跳转到 Foundation 的contains.
  • \n
\n

至于这部分:

\n
\n

语言不应该以某种方式表明这一点吗

\n
\n

恐怕 Stack Overflow 不太擅长回答“应该”的问题。我想说,是的,这有点令人抓狂,但这是我们为将 Swift 轻松无缝地集成到 Cocoa 编程世界而付出的代价的一部分。你可能会争辩说 Swift 的人不应该命名他们的方法contains,但是火车已经离开了车站,而且,这个名字完美地表明了该方法的作用。

\n

另一件需要记住的事情是,除非有 Foundation,否则你可能永远不会真正使用 Swift (可能是因为你有 UIKit 或 SwiftUI 或 AppKit),所以实际上不会出现这个问题。你遇到了一个不寻常的边缘情况,这是值得赞扬的,但是,根据假设,这是不寻常的。

\n
\n

让事情变得更复杂的是,我认为您遇到的 Swift 库方法可能刚刚作为 Xcode 14 和 Swift 5.7 等的一部分引入。请参阅https://developer.apple.com/videos/play/wwdc2022/110354/? time=1415 WWDC \'22 讨论新的 String 功能。在 Xcode 的早期版本中,短语"a".contains("")如果没有 Foundation \xe2\x80\x94,该短语甚至不会被编译,因此问题永远不会出现!

\n

  • 打字错误?“Swift 版本的字符串是 *NSString*”。 (2认同)
  • 感谢您的全面答复。关于这种情况有多常见——我主要使用 Swift 编写调用系统 API 的 CLI,有时这些实际上并不需要 Foundation。在某些情况下,我会尝试添加需要 Foundation 的功能,并发现我编写的内容在导入后其行为发生了变化。通常需要基础,但通常我通常会避免导入库,直到我确定需要它们。使用Swift时可能需要调整这个习惯。 (2认同)
  • 提交了错误报告 https://github.com/apple/swift/issues/62269 (2认同)