深度解析swift中的String

本文深入探讨了Swift中的String结构,包括Character的定义,它实际上是grapheme cluster,以及如何通过组合Unicode代码点形成字符。String是由不确定长度的Character组成,采用双向链表存储,通过String.Index进行访问。文章还介绍了String与NSString之间的自动桥接,以及在Swift中如何使用Range<String.Index>表示字符串区间。推荐阅读相关文档以了解更多详情。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

String 是我们最常用到的语言元素,swift中的String初看起来相当简洁、易用(官方教程),真正大量使用时,却有点摸不着头脑。 第一、String.Index的概念让人费解,不知道它是如何构造出来的,Range<String.Index>就更奇怪了。第二、swift标准库中的方法很少,习惯了NSString中那些强大的功能,难免就要用一下bridge,而两者又有一些不能匹配的东西。 直到看完了这篇文章( http://oleb.net/blog/2014/07/swift-strings/),才算真正的明白了String的奥妙之处。

这篇文章讲的更好:https://developer.apple.com/swift/blog/?id=30

Character
swift中的Character是个奇怪的东西,它是个perceived character,或者说是个grapheme cluster。没有找到合适的中文解释。

举例说明:
let  precomposedCafe  =  "caf \u{E9} "
这个字符串是 café\u{E9}就是最后一个字符 é  

let  decomposedCafe  =  "cafe"  +  " \u{301} "
这个字符串也是 café\u{301}是最后一个字符的上标注

对于用户来讲,这两个字符串是完全相同的东西,count相同、内容也相同。

再看一个例子,韩文中的 한 字(由三个韩文字符拼成):
let  precomposedSyllable :  Character  =  " \u{D55C} "
let  decomposedSyllable :  Character  =  " \u{1112}\u{1161}\u{11AB} "
对于用户来讲,这两个Character也是完全一样的。都会打印出

因为,多个unicode code point可以组合出一个字符,swift的字符串就利用这个特性,向右寻找最大的组合形成一个Character。

String
String就是一堆Character的集合。每个Character所占用的内存空间不定,注定了String不能用普通的数组来存储内容,实际用的是双向链表。

String.Index
既然String是个双向链表,那么,访问其中的某个元素,或者substring,就要用指针了。 就是Index。
startIndex 相当于链表的 head指针, endIndex相当于tail指针。
有个全局函数可以方便指针操作: advance
advance(s.startIndex, 3)
实际上就是调用了3次 successor


String 与 NSString 的自动桥接
swift标准库中String的方法比较少,远远不如NSString那么方便,所以,Apple做了一个很方便的功能 —— 自动桥接。
只要 import Foundation,NSString的 大部分功能都可以被String直接使用,而且,不需要做显式类型转换。 为什么说是大部分功能呢? 因为它们的存储方法不同,NSString的随机访问功能无法支持,例如:characterAtIndex:。若要使用这个功能,必须显示转换成NSString类型。

NSRange 和 Range<String.Index>
NSString中对于字符串区间,可以用NSRange来表示, 而String用的是Range<String.Index>。 对于后者,乍一看有点奇怪,其实它就是一个起始指针加上一个偏移量。因为String.Index本质上是一个指针,那么,字符串a的Index对于字符串b就没有任何意义,这一点需要注意。




参考文档:

详细的概念阐述,精辟!


一些简单又好玩儿的例子:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值