MENU

Swift - 字符串

May 12, 2016 • Read: 491 • Codes

Swift中的字符串(String)是一个Unicode编码、16位字符的字符序列。其和Objective-C中的(NSString)看上去稍微有点不太一样,在Objective-C中,我们定义一个字符串时一般这样:

NSString* aString = @"A String";

而在Swift中,一般这样:

let aString = "A String"

可以看出,在Swift中,定义一个字符串不再需要加上@符号。

不管在Objective-C中还是在Swift中,字符串都是表现出了「值类型语义」,即使在Objective-C中,我们定义一个字符串时仍要加上指针*符号。

在Swift中,字符串被定义成了struct类型,所表现出的也是正常的「值类型」。然而其内部实现却和传统的struct完全不同。真正的字符串内容其实是存放在堆中的,String的内部包含了一个「内容指针」指向堆上的内容。为什么他还保留了struct的特征?主要是其内部采用了特殊的实现方式:

Copy-on-Write 共享技术

在我们定义字符串时,相同内容的字符串只保留同一份堆内存,然后使用「内容指针」指向堆内存。这样,多个struct里的「内容指针」指向了同一份堆内存,即提高了效率,又节省了内存。

同样的,在字符串复制、赋值给其他变量/常量时,只会复制栈上的struct结构体,其中的「内容指针」保持不变,即仍指向同一份堆内存。

而在字符串内容改变时,会先将原来堆内存拷贝一份,并使「内容指针」指向新的对内存地址,然后再更改堆内存中的内容。这样,在完成更改的时候又不会影响到其他「内容指针」相同的变量,保持了「值类型」特征。

而正因此,每当我们需要修改一个字符串时,Swift都会先复制一份,然后再修改,所以,字符串的修改成本会略高一些。因此,我们应该尽量避免一些不必要的字符串修改,在修改字符串时尽量使用appendappendContentsOf方法,并设置适当的Capacity,而不是使用+=符号拼接字符串。

简单使用

初始化
// 以字面量的形式初始化
let aString = "A String"
//上面这代码等价于: 
// let aString:String = "A String"

// 使用String的初始化器初始化
let anotherString = String("What")

// 初始化空字符串,以下两种方式初始化的字符串是相等的
let emptyString = ""
let anotherEmptyString = String()
字符串拼接
// 可以简单的使用`+`号拼接字符串
var combinedString = aString + " " + anotherString    //A String What
// 相当于:combinedString = combinedString + "TF"
combinedString += "TF"                              //A String WhatTF

let aChar: Character = "!"
// Append a Char,会更改自身的值
combinedString.append(aChar)                      //A String WhatTF!
// Append a String,会更改自身的值
combinedString.appendContentsOf("XXX")               //A String WhatTF!XXX
字符串插值
let num = 100
let string = "Hello"
let combinedString = "Num is: \(num), and String is: \(string)"
// "Num is: 100, and String is: Hello"

在上面的例子中,num作为\(num)string作为\(string)被插入到一个字符串常量中。 当创建字符串执行插值计算时此占位符会被替换为numstring的实际值。

我们可以在任何可以使用字符串字面量的时候使用。

判断字符串值是否相等

在Swift中判断值相等使用==操作符,当然String也不例外:

let emptyString = ""
let anotherEmptyString = String()

if emptyString == anotherEmptyString { //相等,输出:emptyString == anotherEmptyString
    print("emptyString == anotherEmptyString")
}

let aString = "Hello"
let anotherString = "Hel" + "lo"

if aString == anotherString { //相等,输出:aString == anotherString
    print("aString == anotherString")
}
遍历字符串的值
for character in "Dog!????".characters {
    print(character)
}
// D
// o
// g
// !
// ????
判断字符串是否为空
let emptyString = ""
if emptyString.isEmpty {
    print("emptyString is Empty")
}

let anotherEmptyString = String()
if anotherEmptyString.isEmpty {
    print("anotherEmptyString is Empty")
}

let notEmptyString = " "
if notEmptyString.isEmpty {
    print("notEmptyString is Empty")
} else {
      print("notEmptyString is not Empty")
}

let anotherNotEmptyString = "Hello"
if anotherNotEmptyString.isEmpty {
    print("anotherNotEmptyString is Empty")
} else {
      print("anotherNotEmptyString is not Empty")
}
截取字符串

在Swift中字符串的下标使用String.CharacterView.Index,而不是Int

下标不能使用初始化器初始化,获取方式如下:

let string = "Hello, This is a swift string.";
let startIndex = string.startIndex                // 0
let endIndex = string.endIndex                    // 30

let afterStartIndex = startIndex.successor()    // 1
let beforeEndIndex = endIndex.predecessor()        // 29

let advancedIndex = startIndex.advancedBy(10)    // 10
let limitedAdvancedIndex = startIndex.advancedBy(100, limit: endIndex) // 30
let anotherLimitedAdvancedIndex = endIndex.advancedBy(-100, limit: startIndex)  // 0

截取字符串使用IndexRange<Index>Range<Index>的创建方法如下:

let range = Range(startIndex ..< endIndex)    // 0..<30
// 或
let anotherRange = startIndex ..< endIndex    // 0..<30

截取字符串:

string.substringToIndex(string.startIndex.advancedBy(5))
// Hello

string.substringFromIndex(string.endIndex.advancedBy(-13))
// swift string.

let range = string.startIndex.advancedBy(7) ..< string.endIndex.advancedBy(-13)

string.substringWithRange(range)
// This is a

string[range]
// This is a
判断是否包含字符串
if string.containsString("swift") {
    print("Contains")
}
查找字符串
let range:Range? = string.rangeOfString("swift")    // 17..<22
let range:Range? = string.rangeOfString("swifty")    // nil
Tags: Swift, String
Archives QR Code Tip
QR Code for this page
Tipping QR Code
Leave a Comment