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. 06 Maven 聚合和继承

    Maven 聚合和继承 1. 聚合 2. 继承 <parent> <groupId>org.apache.karaf.demos</groupId> <art ...

  2. 01 Maven 安装与配置

    Maven 安装与配置 1. Maven 介绍 Maven 翻译为 "专家","内行".Maven 是 Apache 下的一个纯 Java 开发的开源项目,它是 ...

  3. MYSQL 问题小总结

    mysql 问题小总结 1.MySQL远程连接ERROR 2003(HY000):Can't connect to MySQL server on ‘ip’(111)的问题 通常是mysql配置文件中 ...

  4. Ehcache整合spring配置

    为了提高系统的运行效率,引入缓存机制,减少数据库访问和磁盘IO.下面说明一下ehcache和spring整合配置. 1.   需要的jar包 slf4j-api-1.6.1.jar ehcache-c ...

  5. 2018.07.08 hdu1394 Minimum Inversion Number(线段树)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...

  6. Android+PHP开发最佳实践

    本书以一个完整的微博应用项目实例为主线,由浅入深地讲解了Android客户端开发和PHP服务端开发的思路和技巧.从前期的产品设计.架构设计,到客户端和服务器的编码实现,再到性能测试和系统优化,以及最后 ...

  7. (树的直径)LightOJ -- 1094

    链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#problem/C 求树的直径,这里只不过给每条边增加一个边长属性,变成 ...

  8. C++ sort()函数的用法

    C++sort()函数的用法 C++sort()函数的用法 近来看了c++标准库这本书,学到了很多,就把这其中的一点C++sort()函数的用法写下来和大家分享吧! (一)为什么要用c++标准库里的排 ...

  9. Moving XML/BI Publisher Components Between Instances

    As it is well known fact that XMLPublisher stores the metadata and physical files for templates and ...

  10. UniGui之锱铢积累(仔细看这个文件)

    http://www.doc88.com/p-4022977294324.html 这个是Word文档