Swift 里字符串(三)small String

small string, 只有两个 UInt64
的字,这里面存储了所有的信息。
内存布局如下:

第二个 UInt64
存储了标记位和长度信息,以及部分字符串的值
// Get an integer equivalent to the _StringObject.discriminatedObjectRawBits
// computed property.
@inlinable @inline(__always)
internal var rawDiscriminatedObject: UInt64 {
// Reverse the bytes on big-endian systems.
return _storage.1.littleEndian
}
rawbit.1 | 值 | 含义 |
---|---|---|
b63 | 1 | 是不可变的 |
b62 | 0/1 | 是否是ASCII |
b61 | 1 | 是 small string |
b60 | 0 | 可以获取联系utf8 code point |
b59-b56 | 0000~1111 | 已经使用的长度 |
b55~b0 | 存储utf8 code point |
第一个UInt64
存储的都是字符串的值
初始化 small string
最基本的初始化
@inlinable @inline(__always)
internal init(leading: UInt64, trailing: UInt64, count: Int) {
_internalInvariant(count <= _SmallString.capacity)
let isASCII = (leading | trailing) & 0x8080_8080_8080_8080 == 0
let discriminator = _StringObject.Nibbles
.small(withCount: count, isASCII: isASCII)
.littleEndian // reversed byte order on big-endian platforms
_internalInvariant(trailing & discriminator == 0)
self.init(raw: (leading, trailing | discriminator))
_internalInvariant(self.count == count)
}
这是最基本的初始化方法。先根据是否是ASCII
和长度值,生成一个discriminator
。然后把discriminator
和trailing
结合,作为第二个UInt64
。
根据缓存区初始化
// Direct from UTF-8
@inlinable @inline(__always)
internal init?(_ input: UnsafeBufferPointer<UInt8>) {
if input.isEmpty {
self.init()
return
}
let count = input.count
guard count <= _SmallString.capacity else { return nil }
// TODO(SIMD): The below can be replaced with just be a masked unaligned
// vector load
let ptr = input.baseAddress._unsafelyUnwrappedUnchecked
let leading = _bytesToUInt64(ptr, Swift.min(input.count, 8))
let trailing = count > 8 ? _bytesToUInt64(ptr + 8, count &- 8) : 0
self.init(leading: leading, trailing: trailing, count: count)
}
即先判断长度是否超过上限,如果超过,返回nil
。
如果没有超过上限,再调用init(leading: UInt64, trailing: UInt64, count: Int)
方法。
small string 创建过程

Swift 里字符串(三)small String的更多相关文章
- Swift 里字符串(七)stringIndex
在 String 里,用来索引 Character 的,不是整数,而是StringIndex 内部结构 extension String { /// A position of a character ...
- Swift 里字符串(十)修改字符串
以append操作为例 public mutating func append(_ other: String) { if self.isEmpty && !_guts.hasNati ...
- Swift里字符串(五)Native strings
Native strings have tail-allocated storage, which begins at an offset of nativeBias from the storage ...
- Swift 里字符串(四)large sting
对于普通的字符串,对应的_StringObject 有两个存储属性: _countAndFlagsBits: UInt64 _object: Builtin.BridgeObject _countAn ...
- Swift 里字符串(一)概览
感受一下字符串相关的源文件个数  String 概览 是一个结构体 只有一个变量,类型是 _StringGuts  如上所示,String 真正的内容在__StringStorage或者__Sha ...
- [Swift]LeetCode394. 字符串解码 | Decode String
Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...
- Swift 里字符串(九)UTF16View
即以 UTF16 编码的格式来查看字符串. UTF16View 是一个结构体 @_fixed_layout public struct UTF16View { @usableFromInline in ...
- Swift里字符串(六)Shared strings
Shared strings do not have tail-allocated storage, but can provide access upon query to contiguous U ...
- Swift 里字符串(十一)OC 字符串和 Swift 字符串的转换
 to OC func _bridgeToObjectiveCImpl() -> AnyObject { if _guts.isSmall { return _guts.asSmall.wit ...
随机推荐
- 《JavaScript高级程序设计》笔记
1. 当在函数内部定义了其他函数时,就创建了闭包.闭包有权访问包含函数内部的所有变量. 2. 闭包可以分隔变量空间,不会占用全局空间而造成相互间的干拢.使用闭包可以在JavaScript中模仿块级作用 ...
- 2014.1.4 cxf spring webservice
先创建 webservice 服务端 . 首先下载 cxf jar 包 , cxf-2.7.8 . 新建 web 项目 aa . 将下载的cxf 压缩文件解压,将lib 下的jar 全部build p ...
- 2018.08.14 bzoj4241: 历史研究(回滚莫队)
传送们 简单的回滚莫队,调了半天发现排序的时候把m达成了n... 代码: #include<bits/stdc++.h> #define N 100005 #define ll long ...
- fortran write格式
advance="no",就是输出不换行. write(*,"(f10.1)",advance="no")A 格式化输出的控制字符非常的丰富 ...
- 1) Spring_HelloWorld
1. Spring Tool Suite™ 方式一:下载对应eclipse版本的文件,离线安装 4.4.2 springsource-tool-suite-3.6.4.RELEASE-e4.4.2-u ...
- day15(mysql之零碎知识)
数据完整性 实体完整性 实体: 表中一行(一行记录)代替一个实体 实体完整性的作用: 标识每一行数据不重复. 约束类型: 主键约束, 唯一约束,自动增长列. 主键约束: 标识该列唯一,非空. 注: ...
- ajax和SSH请求中乱码的一些解决方法
乱码的原因无非就是两端的编码方式不同. ajax方的编码 ajax无论是get还是post,都可以在content-type中设置charset为utf-8,或者beforesend中在sethead ...
- sklearn 中fit_tansform 与 transform的区别
https://blog.csdn.net/anecdotegyb/article/details/74857055 先fit_transform 后transform,不然会报错.
- 设计模式之外观模式(Facade Pattern)
一.什么是外观模式? 简单的说,外观模式是用来简化接口的. 通常,我们觉得一个子系统不好用,可能是因为它提供的外部接口太接近低层组件,让我们用起来感到很麻烦. 因为我们不需要知道内部细节,我们只想要一 ...
- c++日志输出库 spdlog 简介(3)多线程控制台输出日志
spdlog源码分析:https://www.cnblogs.com/eskylin/p/6483199.html spdlog的异步模式使得spdLog可以支持多线程,于是写了一个多线程的小例子: ...