Swift4字符和字符串

2017-12-08  本文已影响0人  南衍儿

只列出与C语言不同或者在C中不常见的用法

String类型可以作为Character类型的数组来访问
字符串的创建和修改语法非常轻量易读,使用与 C 类似的字符串字面量语法。
字符串串联只需要使用 +运算符即可。

字符串字面量

let someString = "some string literal value"  //使用字符串字面量初始化

上述例子使用了字符串字面量初始化,所以someString被推测为String
多行字符串使用"""初始化(类似Python)

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."
"""

在这个多行格式中,字符串字面量包含了双引号包括的所有行。字符串起始于三个双引号( """ )之后的第一行,结束于三个双引号( """ )之前的一行,也就是说双引号不会开始或结束带有换行。下面两个是一样的

let singleLineString = "These are the same."
let multilineString = """
These are the same.
"""

初始化字符串

两种方法

var emptyString = ""
var anotherEmptyString = String()

字符串是值类型

重要,不同于Objective-C和C,在Swift中字符串是值类型,如果你创建了一个新的 String值, String值在传递给方法或者函数的时候会被复制过去,还有赋值给常量或者变量的时候也是一样。每一次赋值和传递,现存的 String值都会被复制一次,传递走的是拷贝而不是原本。
另一方面,Swift 编译器优化了字符串使用的资源,实际上拷贝只会在确实需要的时候才进行。这意味着当你把字符串当做值类型来操作的时候总是能够有用很棒的性能。

这点和Objective-C不一样,Objective-C中NSString是指针类型。

操作字符串

可以使用for-in操作遍历String中的每个Character

连接操作

字符串插值

也就是其他语言中的格式化输出,字符串插值是一种从混合常量、变量、字面量和表达式的字符串字面量构造新 String值的方法。每一个你插入到字符串字面量的元素都要被一对圆括号包裹,然后使用反斜杠前缀:


let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"

unicode

字符串字面量能包含以下特殊字符:

let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein

let blackHeart = "\u{2665}" // ♥, Unicode scalar U+2665

字符

let exclamationMark:Character = "!"
let catCharacter:[Character] = ["c","a","t"]
let catString = String(catCharacter)
print(catString)

可见,字符串并不等于字符数组,实际上,字符串在Swift中是以双向链表的形式存储的

字符串索引

CharacterString中是一个双向链表的结构,所以String不能通过整数下标来索引
String的索引要使用String.Index对象来索引,有startIndexendIndex等,可以通过偏移量访问其他部分


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

字符串下标不能越界,否则会报错

字符串遍历


let greeting = "Hello"

for index in greeting.indices{

    print("\(greeting[index])",terminator:" ")  //terminator默认为换行
}

// 输出: H e l l o 

插入和删除


var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"
 
welcome.insert(contentsOf:" there".characters, at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there!"


welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
 
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"

子串

重要:当需要使用一个字符串生成子串的时候,是生成了一个SubString的实例,而不是新的一个字符串,大部分String操作可以直接用在SubString上面,可以直接使用操作字符串的方法操作子串。
但是,子串只是对原字符串的暂时操作才使用,如果要将子串结果保存更长时间,需要将子串转化为字符串。

let greeting = "Hello,world!"
let index = greeting.index(of:",") ?? greeting.endIndex
let beginning = greeting[..<index]
//  beginning是"Hello"

// 将子串转换为字符串
let newString = String(begninning)

像字符串一样,子串也有一块内存空间来存储。不同的是,作为性能优化,子串可以重用原始字符串的内存空间(字符串也有类似的优化,即如果两个字符串共享内存地址,则它们相等)。这样的性能优化意味着如果你不改变字符串内容,在使用字符串或者子串的时候不用担心性能。就像上面说的,子串不适合长时间的存储--因为它其实是重用了原字符串的内存,当原字符串在内存中存在的时候,子串才可以用。
在上述的例子中,greeting是一个字符串,所以它有一块内存空间来存储字符。而beginning是子串,所以它重用了greeting的内存空间。而与之不同的,newString是字符串,所以newString开辟了新的内存空间来存储。

字符串比较

使用hasPrefix(_:)hasSuffix(_:)方法

上一篇下一篇

猜你喜欢

热点阅读