参考资料:Swift 编程语言
参考资料:Swift 语言指南
1、Swift 的字符串用 String类型来表示。 String的内容可以通过各种方法来访问到,包括作为 Character值的集合。
2、字符串字面量。字符串字面量是被双引号( ")包裹的固定顺序文本字符。如果你需要很多行的字符串,使用多行字符串字面量。多行字符串字面量是用三个双引号引起来的一系列字符。字符串起始于三个双引号( """)之后的第一行,结束于三个双引号( """)之前的一行。
let quotation = """
The White Rabbit put on his spectacles. "Where shall I begin,
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""
3、要在多行字符串中包含 """,你必须用反斜杠( \)转义至少其中一个双引号。举例来说:
let threeDoubleQuotes = """
Escaping the first quote \"""
Escaping all three quotes \"\"\"
"""
4、多行字符串可以缩进以匹配周围的代码。尾部的三个双引号( """)前的空格会告诉 Swift 其他行前应该有多少空白是需要忽略的。总而言之,如果你在某行的空格超过了结束的双引号( """),那么这些空格会被包含。
4.png
5、通过检查布尔量 isEmpty属性来确认一个 String值是否为空。
6、Swift 的 String类型是一种值类型。如果你创建了一个新的 String值, String值在传递给方法或者函数的时候会被复制过去,还有赋值给常量或者变量的时候也是一样。每一次赋值和传递,现存的 String值都会被复制一次,传递走的是拷贝而不是原本。Swift 的默认拷贝 String行为保证了当一个方法或者函数传给你一个 String值,你就绝对拥有了这个 String值,无需关心它从哪里来。你可以确定你传走的这个字符串除了你自己就不会有别人改变它。
7、可以通过提供 Character类型标注,来创建一个独立的 Character常量或者变量。Character类型只能包含单个字符。
let exclamationMark: Character = "!"
8、可以通过传入一个Character类型的数组作为实际参数,使用初始化器来构造一个String:
let catCharacters: [Character] = ["C", "a", "t", "!", "?"]
let catString = String(catCharacters)
print(catString)
9、字符串插值 ()。
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"
10、字符串索引。每一个 String值都有相关的索引类型, String.Index,它相当于每个 Character在字符串中的位置。
Swift中,不同的字符会获得不同的内存空间来储存,所以为了明确哪个 Character在哪个特定的位置,你必须从 String的开头或结尾遍历每一个 Unicode 标量。因此,Swift 的字符串不能通过整数值索引。
使用 startIndex属性来访问 String中第一个 Character的位置。 endIndex属性就是 String中最后一个字符后的位置。所以说, endIndex属性并不是字符串下标脚本的合法实际参数。如果 String为空,则 startIndex与 endIndex相等。
使用 index(before:) 和 index(after:) 方法来访问给定索引的前后。要访问给定索引更远的索引,你可以使用 index(_:offsetBy:) 方法而不是多次调用这两个方法。
你可以使用下标脚本语法来访问 String索引中的特定 Character。
let greeting = "Guten Tag!"
greeting[greeting.startIndex] // G
greeting[greeting.index(before: greeting.endIndex)] // !
greeting[greeting.index(after: greeting.startIndex)] // u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // a
11、遍历字符串里面的字符。
let string = “hello world”
for index in sting.indices {
print("\(sting[index]) ", terminator: "")
}
12、插入与移除
插入单个字符:string.insert(“!”,at:string.endIndex)
插入字符串:string.insert(contentsOf: " mengmengda”, at: string.endIndex)
移除单个字符:string.remove(at: string.index(before: string.endIndex))
移除字符串:先确定被移除的子串的range,再移除。
let range = string.index(string.endIndex, offsetBy: -3)..<string.endIndex
string.removeSubrange(range)
13、子字符串Substring 不是 String 类型,它们有点区别。当你获得了一个字符串的子字符串——比如说,使用下标或者类似 prefix(_:) 的方法——结果是一个 Substring的实例,不是另外一个字符串。Swift 中的子字符串拥有绝大部分字符串所拥有的方法,也就是说你可以用操作字符串相同的方法来操作子字符串。总之,与字符串不同,在字符串上执行动作的话你应该使用子字符串执行短期处理。当你想要把结果保存得长久一点时,你需要把子字符串转换为 String实例。
let greeting = "Hello, world!"
let index = greeting.index(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
// Convert the result to a String for long-term storage.
let newString = String(beginning)
14、与字符串类似,每一个子字符串都有一块内存区域用来保存组成子字符串的字符。字符串与子字符串的不同之处在于,作为性能上的优化,子字符串可以重用一部分用来保存原字符串的内存,或者是用来保存其他子字符串的内存。(字符串也拥有类似的优化,但是如果两个字符串使用相同的内存,他们就是等价的。)这个性能优化意味着在你修改字符串或者子字符串之前都不需要花费拷贝内存的代价。如同上面所说的,子字符串并不适合长期保存——因为它们重用了原字符串的内存,只要这个字符串有子字符串在使用中,那么这个字符串就必须一直保存在内存里。
在上面的例子中, greeting是一个字符串,也就是说它拥有一块内存保存着组成这个字符串的字符。由于 beginning是 greeting的子字符串,它重用了 greeting所用的内存。不同的是, newString是字符串——当它从子字符串创建时,它就有了自己的内存。下面的图例显示了这些关系:
14.png
15、字符串的比较:== , !=,hasPrefix(:), hasSuffix(:)
16、两个 String值(或者两个 Character值)如果它们的扩展字形集群是规范化相等,则被认为是相等的。如果扩展字形集群拥有相同的语言意义和外形,我们就说它规范化相等,就算它们实际上是由不同的 Unicode 标量组合而成。比如说, LATIN SMALL LETTER E WITH ACUTE( U+00E9)是规范化相等于 LATIN SMALL LETTER E( U+0065)加 COMBINING ACUTE ACCENT( U+0301)的。这两个扩展字形集群都是表示字符é的合法方式,所以它们被看做规范化相等。反而, LATIN CAPITAL LETTER A( U+0041, 或者说 "A")在英语当中是不同于俄语的 CYRILLIC CAPITAL LETTER A( U+0410,或者说 "А")的。字符看上去差不多,但是它们拥有不同的语言意义,所以它们不被看做规范化相等。
网友评论