惊!只是 `import Foundation`,`String.contains("")` 的返回值居然变了?

两行代码,两种结果

是否 import Foundation "".contains("") "abc".contains("")
❌ 纯 Swift true true
✅ + Foundation false false

同一个 API,返回值完全相反,而且大多数 iOS 项目会间接 import Foundation,所以你一直用的其实是 ObjC 版本!

幕后黑手:桥接与方法决议

  1. Swift.String 与 NSString 是 toll-free bridged。
  2. 一旦 import Foundation,编译器会把同名方法 优先桥接到 NSString 的实现。
  3. 两个版本的 contains 签名兼容,但 行为不同:
实现 空子串规则
Swift 原生 空字符串是任何字符串的子串 → true
NSString 空子串不存在 → false

实战影响

  • 绝大多数 iOS/SwiftUI 工程都会间接 import Foundation → 你看到的都是 false。
  • 纯 Swift Package / Linux Server 没 Foundation → 看到的是 true。
  • 跨平台库若依赖空子串行为,务必显式测试两种环境。

避坑清单

场景 建议
写跨平台库 显式单元测试两种 import 状态
需要与 ObjC 对齐 直接使用 Foundation 行为并写注释
想要纯 Swift 行为 自建模块不 import Foundation,或用 Swift-only 方法
不确定当前行为 打印类型或查看 Quick Help 看是 String.contains还是 NSString.contains

一句话总结

只要 import Foundation,你就默认接受了 NSString 的行为。

在写通用逻辑 / 跨平台库 / 纯 Swift Package时,记得给空子串单独写测试,别被"同名不同魂"坑了。

相关推荐
用户38034165882977 小时前
控制中心一键后台录音:我被自己的 Spike 骗了两次
ios·swift
东坡肘子13 小时前
iPhone Duo 留给开发者的一个月 -- 肘子的 Swift 周报 #155
人工智能·swiftui·swift
茶底世界之下2 天前
导出进度不是一个百分比:AVFoundation 收尾阶段的状态建模
ios·swift
茶底世界之下2 天前
为什么媒体源不能在回调仍执行时提前报告 finish?
swift
茶底世界之下2 天前
为什么视频处理器必须提前声明“它能处理什么帧”
swift
茶底世界之下2 天前
录制结束,不代表视频文件已经交付:AVFoundation 录制完成状态的工程化判断
swift
茶底世界之下7 天前
为什么预览、录制、离线导出不能共享同一个背压策略?
ios·swift
2501_915909067 天前
移动端开发工具链怎么组合比较好,iOS、Android、跨端三套配置方案
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
东坡肘子8 天前
一场关于 SwiftUI 动画的“原生”之争 -- 肘子的 Swift 周报 #154
人工智能·swiftui·swift
2501_915918418 天前
iOS编程用什么软件好?主流工具Xcode、AppCode、CodeRunner与新兴快蝎对比
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程