Swift 里字符串(十)修改字符串
以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 里字符串(十)修改字符串的更多相关文章
- zzulioj 1206 字符串的修改 (字符串修改)
不难,理解一下直接过,代码如下: #include<stdio.h> #include<string.h> #include<math.h> #include< ...
- Swift语言指南(十)--字符串与字符
原文:Swift语言指南(十)--字符串与字符 字符串是一段字符的有序集合,如"hellow,world"或"信天翁".Swift 中的字符串由 String ...
- [精校版]The Swift Programming Language--语言指南--字符串和字符 (转)
今天装了10.10.马上就可以实际编写swift了.还是很兴奋啊. 哈哈.字符串和字符是大家最容易打交道的.今天就转一下讲解swift中字符串和字符的文章.希望对大家有帮助. 原文地址:http:// ...
- Python字符串的修改以及传参
前两天去面试web developer,面试官提出一个问题,用JavaScript或者Python实现字符串反转,我选择了Python,然后写出了代码(错误的): #!/usr/bin/env pyt ...
- 在Linux中批量修改字符串的命令
昨天一个朋友忽然问我,在Linux下如何批量修改字符串,当时瞬间懵逼了,完全想不起来....... 今天特意的重温了一下Linux下的一些常用命令,并将这个遗忘的批量修改字符串的命令记录下来(资料来自 ...
- unity里c# gc优化 -字符串
1使用unsafe,直接修改字符串 public static class UnsafeString { public static unsafe void Copy(this string str, ...
- linux查找文件夹下的全部文件里是否含有某个字符串
查找文件夹下的全部文件里是否含有某个字符串 find .|xargs grep -ri "IBM" 查找文件夹下的全部文件里是否含有某个字符串,而且仅仅打印出文件名称 fin ...
- Q: 字符串的修改
题目描述 怎么样,前面的题还可以吧~ 依旧是字符串处理,设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B.这里所说的字符操作共有三种: 1. 删除一个字符: 2. 插入一个字 ...
- String与StringBuffer和StringBuilder的根本区别(String为什么无法修改字符串长度)
从网上看了很多的信息,说的大部分是关于final修饰的原因,却没有详细的解释!根据自己收集的资料,跟大家分享一下我的观点(有错请指正).1.我们都知道在修改字符串长度的时候,StringBuffer和 ...
- 随笔 JS 字符串 分割成字符串数组 并动态添加到指定ID的DOM 里
JS /* * 字符串 分割成字符串数组 并动态添加到指定ID的DOM 里 * @id 要插入到DOM元素的ID * * 输入值为图片URL 字符串 * */ function addImages(i ...
随机推荐
- gitlab VS github
gitlab 和 github的比较 GitLab - 基于Git的项目管理软件 GitLab 是一个用于仓库管理系统的开源项目.使用Git作为代码管理工具,并在此基础上搭建起来的web服务.
- composer 安装扩展失败的决绝方法
https://getyii.com/topic/32
- DB2 runstats、reorgchk、reorg 命令【转载】
1.runstats runsats可以搜集表的信息,也可以搜集索引信息.作为runstats本身没有优化的功能,但是它更新了统计信息以后,可以让DB2优化器使用最新的统计信息来进行优化,这样优化的效 ...
- 都有哪些 cache ?
1. spring http://www.springframework.org/schema/cache 2. ehcache LOGO关键词:palindrome [ˈpælɪndrəʊm] 正读 ...
- MFC框架仿真<二>
- MessageBox的常见用法
一 函数原型及参数 function MessageBox(hWnd: HWND; Text, Caption: PChar; Type: Word): Integer; hWnd:对话框父窗口句柄, ...
- java细节问题
保留两位小数:1.234, 1.23, 1.2, 1.0, 1. package test; import java.math.BigDecimal; import java.text.Decimal ...
- 2014年誓言:干掉网页设计程序——Dreamweaver!
2014年誓言:干掉网页设计程序——Dreamweaver! 阅读: 评论: 作者:Rybby 日期: 来源:rybby.com 2014年,我写下誓言,用自己设计的在线网页设计工具“拉拉变” ...
- 集合(六)LinkedHashMap
上两篇文章讲了HashMap和HashMap在多线程下引发的问题,说明了,HashMap是一种非常常见.非常有用的集合,并且在多线程情况下使用不当会有线程安全问题. 大多数情况下,只要不涉及线程安全问 ...
- Delphi XE6 Android拨号函数
http://blog.sina.com.cn/s/blog_44fa172f0101rpex.html Delphi XE6 Android拨号函数 (2014-05-07 17:48:51) 转载 ...