Swift 3 字符串的进化

原文: Updating Strings for Swfit 3
作者: kharrison
译者: kemchenj

我去年写了一篇 Swift String Cheat Sheet 来帮助我记忆如何使用 Swift 标准库里的那些难用的 API, 在痛苦的版本迁移之后, Swift 3有了明显的改善, 这一部分得归功于新的 API 命名规范, 还有 Collections 集合, indicates 索引和 ranges 范围的一种新的运作方式.

这里有我关于 Swift 3的迁移工作的总结 Swift playground.

更好的 API 命名

标准库采用了新的 API 命名规范 API guidelines 之后, String 的属性和方法都有了很多改变. 因为大部分 API 命名的变化 Xcode 都会自动帮你修正, 所以我不会在这里把全都都列出来. 这里列出一些典型的改变让你能更好的了解这次变化:

初始化一个 String

标准库把 String 的初始化方法 init(count: repeatedValue:) 改成了 init(repeating: count:), repeatedValue 的类型也从 Character 字符换成了 String 字符串去获得更多灵活性:

// Swift 2
let h = String(count:3, repeatedValue:"0") // "000"

// Swift 3
let h = String(repeating:"01", count:3)    // 010101

大小写转换

uppercaseString 和 lowercaseString 两个属性现在变成了函数, 重新命名为 uppercased() 和 lowercased():

let mixedCase = "AbcDef"

// Swift 2
// let upper = mixedCase.uppercaseString // "ABCDEF"
// let lower = mixedCase.lowercaseString // "abcdef"

// Swift 3
let upper = mixedCase.uppercased()       // "ABCDEF"
let lower = mixedCase.lowercased()       // "abcdef"

接下来我还会讲到一些别的命名的变化

使用索引去访问集合

Swift 3 里对于 String 影响最大的一个变化就是 new model for collections and indices. 总结起来就是你不能直接访问 String 里的元素, 而必须使用索引去从集合里把元素取出来:

let country = "España"
country.characters       // characters
country.unicodeScalars   // Unicode scalar 21-bit codes
country.utf16            // UTF-16 encoding
country.utf8             // UTF-8 encoding

Swift 3里每个集合的 view 里的 startIndex 和 endIndex 属性还是没变:

let hello = "hello"
let helloStartIndex = hello.characters.startIndex // 0

如果想要获取字符的集合, 你也可以使用 characters 属性:

(译者注: characters 能够自动帮助我们处理编码问题, 让我们获得人类理解的"字符集合". Swift 的字符串 API 刚接触可能会觉得很难用, 但了解了背后的原理之后, 会发现它其实做了很多, 帮我们避开了很多坑, 了解方法之后也很容易使用)

let startIndex = hello.startIndex // 0
let endIndex = hello.endIndex     // 5
hello[startIndex]                 // "h"

之前通过增减索引去访问字符串的方式改变了, successor(), predecessor() 和 advancedBy(n) 的函数都去掉了.

// Swift 2
hello[hello.startIndex]                // "h"
hello[hello.startIndex.successor()]    // "e"
hello[hello.endIndex.predecessor()]    // "o"
hello[hello.startIndex.advancedBy(2)]  // "l"

现在在 Swift 3 里你会使用 index(after:), index(before:) 和 index(_: offsetBy:) 去处理相同的情况:

// Swift 3
hello[hello.startIndex]                // "h"
hello[hello.index(after: startIndex)]  // "e"
hello[hello.index(before: endIndex)]   // "o"

hello[hello.index(startIndex, offsetBy: 1)]  // "e"
hello[hello.index(endIndex, offsetBy: -4)]   // "e"

你也可以给 offset 加上限制, 避免错误的下标访问. 函数 index(_: offsetBy: limitedBy:) 会返回一个可选值, 下标越界的时候就会返回 nil:

if let someIndex = hello.index(startIndex,
                   offsetBy: 4, limitedBy: endIndex) {
  hello[someIndex] // "o"
}

找到第一个符合条件的元素<T>的方式(在这种情况下, T 是一个字符串):

let matchedIndex = hello.characters.index(of: "l") // 2
let nomatchIndex = hello.characters.index(of: "A") // nil

最后, 获取两个索引之间距离的方法现在也被重新命名了:

// Swift 2
let distance = word1.startIndex.distanceTo(indexC)

// Swift 3
let distance = word1.distance(from: word1.startIndex, to: indexC)

使用 Ranges (范围)

Swift 3 里对 Ranges 进行了修改. 假设我有字符集合的一个起始索引值和一个终点索引值:

let fqdn = "useyourloaf.com"
let tldEndIndex = fqdn.endIndex
let tldStartIndex = fqdn.index(tldEndIndex, offsetBy: -3)

用起始和终点索引去初始化 Range 的方式:

let range = Range(uncheckedBounds: (lower: tldStartIndex, upper: tldEndIndex))
fqdn[range]  // "com"

创建一个范围最简单的方法就是使用 ..< 和 ... 操作符:

let endOfDomain = fqdn.index(fqdn.endIndex, offsetBy: -4)
let rangeOfDomain = fqdn.startIndex ..< endOfDomain
fqdn[rangeOfDomain] // useyourloaf

查找和返回子字符串的范围:

if let rangeOfTLD = fqdn.range(of: "com") {
  let tld = fqdn[rangeOfTLD]                 // "com"
}

Playground

你可以在这里找到一份完整的升级后的 API 变化的 playground 文件 Code Examples repository. 我也更新了之前我写的那篇文章 original post.

参考阅读

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 16,913评论 4赞 61
  • 习惯六 统合综效 【统合综效的基本心态是:如果一位具有相当聪明才智的人跟我意见不同,那么对方的主张必定有我尚未体会...
    雪23阅读 287评论 0赞 0
  • 喜欢的歌就会像自己的孩子一样,容不得别人说她/他的不好。。。。。 我的孩子们呐,一直以来你们都是最能给我安慰的 所...
    顾君一笑阅读 906评论 0赞 3
  • 我起床了,发现身边睡着一个女人。 她是我的妻子,是杰出的美人也是杰出的生物科学家!能找到她这样的妻子,我很幸福。 ...
    小小小2014阅读 357评论 0赞 0
  • 《你是我心中的伤》 文/白传英 你现在怎么想 是否和过去一个样 我在你的眼里 没有一次能够顺理成章 ...
    白清风阅读 307评论 0赞 0

友情链接更多精彩内容