append操作为例

  public mutating func append(_ other: String) {
if self.isEmpty && !_guts.hasNativeStorage {
self = other
return
}
self._guts.append(other._guts)
}

_StringGuts 做了实际的工作

下面是实际进行append的地方

  internal mutating func append(_ slicedOther: _StringGutsSlice) {
defer { self._invariantCheck() } if self.isSmall && slicedOther._guts.isSmall {
// TODO: In-register slicing
let smolSelf = self.asSmall
if let smol = slicedOther.withFastUTF8({ otherUTF8 in
return _SmallString(smolSelf, appending: _SmallString(otherUTF8)!)
}) {
self = _StringGuts(smol)
return
}
}
// 进行 copy-on-write 操作
prepareForAppendInPlace(otherUTF8Count: slicedOther.utf8Count) if slicedOther.isFastUTF8 {
let otherIsASCII = slicedOther.isASCII
slicedOther.withFastUTF8 { otherUTF8 in
self.appendInPlace(otherUTF8, isASCII: otherIsASCII)
}
return
} _foreignAppendInPlace(slicedOther)
}

首先判断是否可以安装小字符串处理,然后是重头戏。
我们以实际存储的是native string为例分析。

分配内存操作

  private mutating func prepareForAppendInPlace(
otherUTF8Count otherCount: Int
) {
defer {
_internalInvariant(self.uniqueNativeUnusedCapacity != nil,
"growth should produce uniqueness")
_internalInvariant(self.uniqueNativeUnusedCapacity! >= otherCount,
"growth should produce enough capacity")
} // See if we can accomodate without growing or copying. If we have
// sufficient capacity, we do not need to grow, and we can skip the copy if
// unique. Otherwise, growth is required.
let sufficientCapacity: Bool
if let unused = self.nativeUnusedCapacity, unused >= otherCount {
sufficientCapacity = true
} else {
sufficientCapacity = false
}
//naivestorage的字符串,一定不是UniqueNative的
if self.isUniqueNative && sufficientCapacity {
return
} let totalCount = self.utf8Count + otherCount // Non-unique storage: just make a copy of the appropriate size, otherwise
// grow like an array.
let growthTarget: Int
if sufficientCapacity {
growthTarget = totalCount
} else {
growthTarget = Swift.max(
totalCount, _growArrayCapacity(nativeCapacity ?? 0))
}
//最后会走到这里来
self.grow(growthTarget)
}

一定会调用grow函数。

  internal mutating func grow(_ n: Int) {
defer { self._invariantCheck() } _internalInvariant(
self.uniqueNativeCapacity == nil || self.uniqueNativeCapacity! < n) let growthTarget = Swift.max(n, (self.uniqueNativeCapacity ?? 0) * 2) if _fastPath(isFastUTF8) {
let isASCII = self.isASCII
let storage = self.withFastUTF8 {
// 分配了内存
__StringStorage.create(
initializingFrom: $0, capacity: growthTarget, isASCII: isASCII)
} self = _StringGuts(storage)
return
} _foreignGrow(growthTarget)
}

grow函数里,分配了内存

在分配好的内存里进行内存copy

  internal mutating func appendInPlace(
_ other: UnsafeBufferPointer<UInt8>, isASCII: Bool
) {
self._object.nativeStorage.appendInPlace(other, isASCII: isASCII) // We re-initialize from the modified storage to pick up new count, flags,
// etc.
self = _StringGuts(self._object.nativeStorage)
}
  @_effects(releasenone)
internal func appendInPlace(
_ other: UnsafeBufferPointer<UInt8>, isASCII: Bool
) {
_internalInvariant(self.capacity >= other.count)
let srcAddr = other.baseAddress._unsafelyUnwrappedUnchecked
let srcCount = other.count
self.mutableEnd.initialize(from: srcAddr, count: srcCount)
_postAppendAdjust(appendedCount: srcCount, appendedIsASCII: isASCII)
}

Swift 里字符串(十)修改字符串的更多相关文章

  1. zzulioj 1206 字符串的修改 (字符串修改)

    不难,理解一下直接过,代码如下: #include<stdio.h> #include<string.h> #include<math.h> #include< ...

  2. Swift语言指南(十)--字符串与字符

    原文:Swift语言指南(十)--字符串与字符 字符串是一段字符的有序集合,如"hellow,world"或"信天翁".Swift 中的字符串由 String ...

  3. [精校版]The Swift Programming Language--语言指南--字符串和字符 (转)

    今天装了10.10.马上就可以实际编写swift了.还是很兴奋啊. 哈哈.字符串和字符是大家最容易打交道的.今天就转一下讲解swift中字符串和字符的文章.希望对大家有帮助. 原文地址:http:// ...

  4. Python字符串的修改以及传参

    前两天去面试web developer,面试官提出一个问题,用JavaScript或者Python实现字符串反转,我选择了Python,然后写出了代码(错误的): #!/usr/bin/env pyt ...

  5. 在Linux中批量修改字符串的命令

    昨天一个朋友忽然问我,在Linux下如何批量修改字符串,当时瞬间懵逼了,完全想不起来....... 今天特意的重温了一下Linux下的一些常用命令,并将这个遗忘的批量修改字符串的命令记录下来(资料来自 ...

  6. unity里c# gc优化 -字符串

    1使用unsafe,直接修改字符串 public static class UnsafeString { public static unsafe void Copy(this string str, ...

  7. linux查找文件夹下的全部文件里是否含有某个字符串

    查找文件夹下的全部文件里是否含有某个字符串  find .|xargs grep -ri "IBM"  查找文件夹下的全部文件里是否含有某个字符串,而且仅仅打印出文件名称  fin ...

  8. Q: 字符串的修改

    题目描述 怎么样,前面的题还可以吧~ 依旧是字符串处理,设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1. 删除一个字符: 2. 插入一个字 ...

  9. String与StringBuffer和StringBuilder的根本区别(String为什么无法修改字符串长度)

    从网上看了很多的信息,说的大部分是关于final修饰的原因,却没有详细的解释!根据自己收集的资料,跟大家分享一下我的观点(有错请指正).1.我们都知道在修改字符串长度的时候,StringBuffer和 ...

  10. 随笔 JS 字符串 分割成字符串数组 并动态添加到指定ID的DOM 里

    JS /* * 字符串 分割成字符串数组 并动态添加到指定ID的DOM 里 * @id 要插入到DOM元素的ID * * 输入值为图片URL 字符串 * */ function addImages(i ...

随机推荐

  1. 3层+SVN学习笔记(2)

    在对于餐桌付款程序设计时,需要先选中餐桌,然后点击付款.正常情况是这样的: 在程序设计时,没有考虑到用户未点击餐桌而直接进行付款的情况,程序出现以下错误: 在设计时,需要考虑用户未点击餐桌而直接进行付 ...

  2. spring cloud--------------------HystrixCommand使用

    一.注解使用: (一)注解同步执行 1.注解开启断路器功能 @EnableCircuitBreaker 2.方法事例 @HystrixCommand(fallbackMethod = "er ...

  3. Django入门指南-第9章:静态文件设置(完结)

    http://127.0.0.1:8000 #下一步是告诉Django在哪里可以找到静态文件.打开settings.py,拉到文件的底部,在STATIC_URL后面添加以下内容: STATICFILE ...

  4. Navicat如何导出数据库的svg、pdf,png图片

    有时候各位可能有这么一种感觉,如果一个数据库中的表太多的话,查看起来不大方便,如果你习惯用navicat软件来查看er图的话,那也是更困难了,这里介绍一种方法,就是把这些关系结构导出一个可以用浏览器打 ...

  5. Robot Perception for Indoor Navigation《室内导航中的机器人感知》

    Felix Endres 论文下载 Technische Fakult¨ atAlbert-Ludwigs-Universit¨ at Freiburg Betreuer: Prof. Dr. Wol ...

  6. python实现base64算法加密

    python本身有base64加密的模块,不过是用C写的,封装成了.so文件,无法查看源码,本着学习的心态,自己实现了一遍,算法 原理参考 浅谈Base64编码算法. 代码如下: # coding:u ...

  7. (并查集)Connections in Galaxy War -- zoj --3261 还没写

    链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 http://acm.hust.edu.cn/vjudge/ ...

  8. vim 配置半透明

    转载两个博客 链接一 链接二

  9. hdu 2780 Su-Su-Sudoku(DFS数独)

    题目链接:hdu2780 #include<stdio.h> #include<string.h> #include<queue> #include<math ...

  10. 关于ListBox的几个问题

    Winfrom ListBox绑定数据源list界面不更新问题与绑定数据源不可CRUD问题 场景:获取一个listbox的选中项添加到另一个listbox中 解决方案-1:不要直接绑定DataSour ...