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. c++ 博客资源

    /************************************************************** 技术博客 http://www.cnblogs.com/itdef/   ...

  2. EnrichPipeline文档

    https://sourceforge.net/projects/enrichmentpipeline/

  3. Jigloo 下载 安装 GUI

    这个需要授权,一直不能解决!! 网上找了很多,都觉不能访问,这个可以用Eclipse直接更新的 http://www.cloudgardensoftware.com/jigloo/update-sit ...

  4. MyEclipse配置Maven插件

    一.工具环境 1.jdk-7u80-windows-x64 2.apache-tomcat-7.0.70 3.apache-maven-3.3.9 4.MyEclipse 10.7 5.windows ...

  5. 2018.09.30 bzoj2223: [Coci 2009]PATULJCI(主席树)

    传送门 主席树经典题目. 直接利用主席树差分的思想判断区间中数的个数是否合法然后决定左走右走就行了. 实际上跟bzoj3524是同一道题. 代码: #include<bits/stdc++.h& ...

  6. js级联出生日期

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. hadoop 学习之异常篇

    本文旨在给予自己在学习hadoop过程中遇到的问题的一个记录和解决方法. 一. copyFromLocal: java.io.IOException: File /user/hadoop/slaves ...

  8. Spring bean加载2--FactoryBean情况处理

    Spring bean加载2--FactoryBean情况处理 在Spring bean加载过程中,每次bean实例在返回前都会调用getObjectForBeanInstance来处理Factory ...

  9. (线段树 区间合并更新)Tunnel Warfare --hdu --1540

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1540 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  10. RxJava2 源码分析

    前言 很多项目使用流行的Rxjava2 + Retrofit搭建网络框架,Rxjava现在已经发展到Rxjava2,之前一直都只是再用Rxjava,但从来没有了解下Rxjava的内部实现,接下来一步步 ...