Swift4.0 新特性----字符串改进

注:文章转自这里

1.Unicode 字符串在计算 count 时的正确性改善


在 Unicode 中,有些字符是由几个其它字符组成的,比如 é 这个字符,它可以用 \u{E9} 来表示,也可以用 e 字符和上面一撇字符组合在一起表示 \u{65}\u{301}。
看以下代码
var family = "x"
family += "\u{200D}x"
family += "\u{200D}x" 
family += "\u{200D}x"
print(family)
print(family.characters.count)

这个 family 是一个由多个字符组合成的字符,打印出来的结果是一个特殊的emoji表情。上面的代码在 Swift 3 中打印的 count 数是 4,在 Swift 4 中打印出的 count 是 1。


2.更快的字符处理速度


Swift 4 的字符串优化了底层实现,对于英语、法语、德语、西班牙语的处理速度提高了 3.5 倍。
对于简体中文、日语的处理速度提高了 2.5 倍。(数据来源于官方PPT)


3.去掉 characters


Swift 3 中的 String 需要通过 characters 去调用属性方法,在 Swift 4 中可以通过 String 对象本身直接调用,例如:
let values = "one,two,three..."
var i = values.characters.startIndex
while let comma = values.characters[i...<values.characters.endindex].index(of: ",") {
    if values.characters[i..<comma] == "two" {
        print("found it!")
    }
    i = values.characters.index(after: comma)
}


Swift 4 可以把上面代码中的所有的 characters 都去掉,修改如下:
let values = "one,three..."
var i = values.startIndex
while let comma = values[i...<values.endindex].index(of: ",") {
    if values[i..<comma] == "two" {
        print("found it!")
    }
    i = values.index(after: comma)
}



4.One-sided Slicing


Swift 4 新增了一个语法糖 ... 可以对字符串进行单侧边界取子串。
Swift 3:
let values = "abcdefg"
let startSlicingIndex = values.index(values.startIndex,offsetBy: 3)
let subvalues = values[startSlicingIndex..<values.endindex]

Swift 4:
let values = "abcdefg"
let startSlicingIndex = values.index(values.startIndex,offsetBy: 3)
let subvalues = values[startSlicingIndex...] // One-sided Slicing



5.String 当做 Collection 来用


Swift 4 中 String 可以当做 Collection 来用,并不是因为 String 实现了 Collection 协议,而是 String 本身增加了很多 Collection 协议中的方法,使得 String 在使用时看上去就是个 Collection。例如:
翻转字符串:
let abc: String = "abc"
print(String(abc.reversed()))
// cba


遍历字符:
let abc: String = "abc"
for c in abc {
    print(c)
}
/*
a
b
c
*/


Map、Filter、Reduce:
// map
let abc: String = "abc"
_ = abc.map {
    print($0.description)
}
// filter
let filtered = abc.filter { $0 == "b" }
// reduce
let result = abc.reduce("1") { (result,c) -> String in
    print(result)
    print(c)
    return result + String(c)
}
print(result)




6.Substring


在 Swift 中,String 的背后有个 Owner Object 来跟踪和管理这个 String,String 对象在内存中的存储由内存起始地址、字符数、指向 Owner Object 指针组成。Owner Object 指针指向 Owner Object 对象,Owner Object 对象持有 String Buffer。当对 String 做取子字符串操作时,子字符串的 Owner Object 指针会和原字符串指向同一个对象,因此子字符串的 Owner Object 会持有原 String 的 Buffer。当原字符串销毁时,由于原字符串的 Buffer 被子字符串的 Owner Object 持有了,原字符串 Buffer 并不会释放,造成极大的内存浪费。


在 Swift 4 中,做取子串操作的结果是一个 Substring 类型,它无法直接赋值给需要 String 类型的地方。必须用 String() 包一层,系统会通过复制创建出一个新的字符串对象,这样原字符串在销毁时,原字符串的 Buffer 就可以完全释放了。
let big = downloadHugeString()
let small = extractTinyString(from: big)
mainView.titleLabel.text = small // Swift 4 编译报错
mainView.titleLabel.text = String(small) // 编译通过



7.多行字符串字面量


Swift 3 中写很长的字符串只能写在一行。
func tellJoke(name: String,character: Character) {
    let punchline = name.filter { $0 != character }
    let n = name.count - punchline.count
    let joke = "Q: Why does \(name) have \(n) \(character)'s in their name?\nA: I don't kNow,why does \(name) have \(n) \(character)'s in their name?\nQ: Because otherwise they'd be called \(punchline)."
    print(joke)
}
tellJoke(name: "Edward Woodward",character: "d")

字符串中间有换行只能通过添加 \n 字符来代表换行。

Swift 4 可以把字符串写在一对 """ 中,这样字符串就可以写成多行。
func tellJoke(name: String,character: Character) {
    let punchline = name.filter { $0 != character }
    let n = name.count - punchline.count
    let joke = """
        Q: Why does \(name) have \(n) \(character)'s in their name?
        A: I don't kNow,why does \(name) have \(n) \(character)'s in their name?
        Q: Because otherwise they'd be called \(punchline).
        """
    print(joke)
}
tellJoke(name: "Edward Woodward",character: "d")

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...