下文部分内容成于2018年
本文继续上一篇Swift Practices & Perls (1), 记录标准库学习过程中的技巧.
标准库拾遗
Swift 标准库提供的 API 强大而优雅. 这里归纳总结了一些网上不常见的点.
String
和其他类型之间的转换
一方面, 标准库中存在多个 protocol, 来关联自定义类型和String
. 通常, 在需要按文本格式打印某个对象, 或涉及到用文本进行序列化/反序列化时, 可能会使用到这些 protocol.
ExpressibleByStringLiteral
(旧名StringLiteralConvertible
). 遵循该 protocol 的类型, 支持使用 string literal 初始化.CustomStringConvertible
和CustomDebugStringConvertible
. 支持最基本的输出到一个String
.LosslessStringConvertible
. 该 protocol 继承自CustomStringConvertible
. 与后者不同的是, 该 protocol 的遵循者必须提供和String
之间双向的精确转化. 因此某种意义上说, 遵循本 protocol 的类型转化成的String
可用范围更广, 不限于 debug/print. 因为不用担心2个不同的对象对应到同一个String
.TextOutputStreamable
. 支持按流式增量添加到已有的 stream 的末尾. 因为支持增量添加, 所以遵循者实际实现时, 可能和其他输出String
的 protocol 相比, 内存占用上可以有一些优化.
另一方面, String
本身也存在好几种 initializer. 标准库建议我们使用String
的各种初始化方法, 而不要直接调用上面各个 protocol 定义的方法.
init<T>(_ value: T, radix: Int = default, uppercase: Bool = default)
. 把Int
按某个进制转换成String
.init<T>(_ value: T) where T : LosslessStringConvertible
.init<Subject>(describing: Subject)
. 优先使用TextOutputStreamable
的实现, 最后使用CustomDebugStringConvertible
的实现, 偏向精准性.init<Subject>(reflecting: Subject)
. 优先使用CustomDebugStringConvertible
, 最后使用TextOutputStreamable
, 偏向debug.
Comparisons
在STL中, 并非所有可比的对象都直接遵循Comparable
, 但一定要求最终的底层 element 对象是遵循的.
对于不直接遵循Comparable
的类型来说, 他们比较各自对象的方式无外乎通过 operator 或 method.