【Swift】String与Sbustring区别与联系

文章详细介绍了Swift中String和Substring的区别与工作原理。String是值类型,副本操作可能导致效率降低,而Substring是对原始字符串的引用,更高效但需注意生命周期管理。Substring通过内部的_range属性存储对原始字符串的引用,避免额外内存分配,但也可能延长基础字符串的生命周期。
摘要由CSDN通过智能技术生成
  • String 还是字符串,始终如一。
  • Substring 是string的切片。它们与base string共享内存buffer,并拥有一对范围索引。
  • StringProtocol 抽取出字符串的特征以及如何访问其功能,放进一个协议中。StringSubstring都遵循StringProtocol

img

字符串在不同的 Swift 版本中变化比较大。在 Swift 4 中,当需要从一个字符串中获取子串时,我们获取到的是 Substring 类型而不是一个 String 类型的值。为什么会这样?在 Swift 中,字符串是值类型。这意味着如果想从一个字符串中生成一个新的字符串,则需要做拷贝处理。这对于稳定性是有益的,但效率却不高。

从另一方面讲,一个 Substring 则是对其原始 String 的一个引用。它不需要做拷贝操作,所以更加高效。但是有另一个问题,假设我们要从一个很长的字符串中获取一个长度为 10 的 Substring,由于这个 Substring 会引用 String,那么只要 Substring 一直存在,String 就必须一直存在。所以,任何时候当处理完 Substring 后,需要将其转换为 String。

let myString = String(mySubstring)

这样只会拷贝子串,而原来的字符串可以被正确地回收。Substring 作为一种类型,本身即表示临时存在的。

在 Swift 4 另一个大的改进是字符串又成为集合了。这意味着在集合上的所有操作,也可以应用在字符串中(如下标、迭代字符、过滤等)。

Substring内部

substring的一部分魔法是重用了“parent” string的内存。你可以认为substring由base stringrange构成。

img

这意味着从一个8000字符的string上切一个100字符的substring不需要分配额外内存,也不用复制100个字符。

这也意味着你可能无意延长了你的base string的生命周期。如果你有一个超大字符串存了一整本小说,然后从其中切片了一个单词,那么只要substring还在,这个巨大的string就会一直阴魂不散。

那么到底substring内部是如何跟踪这些的呢?

public struct Substring {
  internal var _slice: RangeReplaceableBidirectionalSlice<String>

内部的 _slice属性保存了关于base string的所有信息:

// 仍然是 Substring 的代码
internal var _wholeString: String {
  return _slice._base
}
public var startIndex: Index { return _slice.startIndex }
public var endIndex: Index { return _slice.endIndex }

计算属性 _wholeString(返回原来完整的字符串),以及 startIndexendIndex (指出在string中切片的范围)只是简单的传递了内部切片属性的值。

你也能看到切片如何用 _base来保存原始string的信息。

参考:
https://www.jianshu.com/p/90adf8ce7b9a

https://blog.csdn.net/weixin_34054931/article/details/87979393

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值