swift 为什么在导入Foundation时String.contains的行为不同?

b5lpy0ml  于 2022-11-28  发布在  Swift
关注(0)|答案(1)|浏览(113)

刚开始学习雨燕,我真的很困惑以下行为.
这是我在运行String.contains时得到的结果,但没有基础:

"".contains("") // true
"a".contains("") // true
"a".contains("a") // true
"" == "" // true

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

import Foundation

"".contains("") // false
"a".contains("") // false
"a".contains("a") // true
"" == "" // true

为什么不同的结果取决于我是否导入Foundation?是否有其他这样的差异,是否有一个详尽的列表?在Foundation文档中没有找到任何内容,但这似乎是重要的文件。我只知道this其他示例。
还有:* 这是如何 * 发生的,这正常吗?我知道Swift有一些扩展,一旦包含了某个东西的每个示例,它们就会改变它们的行为,但可以肯定的是,这应该只是增加行为,而不是改变现有的行为。如果现有的行为被改变了,语言难道不应该以某种方式表明这一点吗?比如,如果我想要不同的行为,让我使用不同的类型?

93ze6v8z

93ze6v8z1#

基本上,这与我回答的问题here相同。
Foundation不是Swift的一部分,它是可可的一部分,Cocoa是比Swift早很多很多年的老Objective-C库。Foundation的字符串版本是NSString。但是Swift String是“桥接”到NSString的,所以一旦导入Foundation,一堆NSString方法就会活跃起来,就好像它们是Swift String的一部分一样,尽管它们不是。在您的例子中,您实际上最终调用了一个完全不同的方法,正如您所发现的,该方法会给出不同的结果。
要了解这一点,一个很好的方法是在代码中按住Command键并单击术语contains(或者更好的方法是按住Option键并单击它,然后单击Open in Developer Documentation):

  • 如果你还没有导入Foundation(或UIKit),你会跳到Swift String的contains
  • 如果您 * 已 * 导入Foundation,则会跳转到Foundation的contains

对于本部分:
难道语言不应该以某种方式表明这一点吗
我担心Stack Overflow在“应该”的问题上不是很擅长。我想说,是的,这有点让人抓狂,但这是我们为Swift轻松无缝地集成到可可编程世界中所付出的代价的一部分。你可能会争辩说Swift的人不应该将他们的方法命名为contains,但火车已经离开了车站,而且,它是一个能很好地说明方法用途的名称。
另一件需要记住的事情是,你可能永远不会 * 真正 * 使用Swift *,除非 * 在Foundation面前(也许是因为你在UIKit或SwiftUI或AppKit面前),所以实际上这个问题不会出现。你遇到了一个不寻常的边缘情况,这是值得称赞的,但 * 根据假设 *,不寻常。
让事情变得更复杂的是,我认为您遇到的Swift库方法可能是作为Xcode 14和Swift 5.7等的一部分引入的。请参见https://developer.apple.com/videos/play/wwdc2022/110354/?time=1415,了解WWDC '22对新String特性的讨论。在Xcode的早期版本中,如果没有Foundation,短语"a".contains("")甚至不会编译-因此问题永远不会出现!

相关问题