Swift 的 String 类型与 Foundation NSString 类进行了无缝桥接。如果您利用 Cocoa 或 Cocoa Touch 中的 Foundation 框架进行工作,整个 NSString API 都可以调用您创建的任意 String 类型的值,除了本章介绍的String特性。您也可以在任意要求传入NSString 实例作为参数的 API 中使用 String 类型的值进行替换。
var emptyString = ""
var anotherEmptyString = String()
这两者是等价的,就是说 emptyString== anotherEmptyString。
判断字符串是否为空
if emptyString.isEmpty{
println("Nothing to see here.")
}
在Swift中可以通过将字符串赋值给一个常量或者变量来标示字符串可不可以修改。
注意:在 Objective-C 和 Cocoa 中,您通过选择两个不同的类( NSString 和 NSMutableString )来指定该字符串是否可以被修改,Swift中的字符串是否可以修改仅通过定义的是变量还是常量来决定,实现了多种类型可变性操作的统一。
var variableString = "Horse" //可变类型
variableString += " and carriage"
let constantString = "Highlander" //不可变类型
//constantString += " and another Highlander." //编译错误
Swift 的 String 类型是值类型。如果您创建了一个新的字符串值,那么当其进行常量、变量赋值操作或在函数/方法中传递时,会进行值拷贝。在不同情况下,都会对已有字符串值创建新副本,并对该新副本进行传递或赋值。
注意:和Cocoa 中的 NSString 不同,当您在 Cocoa 中创建了一个 NSString 实例,并将其传递给一个函数/方法,或者赋给一个变量,您永远都是传递或赋值同一个 NSString 实例的一个引用。除非您特别要求其进行值拷贝,否则字符串不会进行赋值新副本操作。
Swift 默认字符串拷贝的方式保证了在函数/方法中传递的是字符串的值,其明确您独有该字符串的值,无论它来自哪里。您可以放心您传递的字符串本身不会被更改,除非是你自己更改它。
在实际编译时,Swift编译器会优化字符串的使用,使实际的复制只发生在绝对必要的情况下,这意味着您始终可以将字符串作为值类型的同时获得极高的性能。
Swift中的String类型是特定序列的字符的集合。你可以用for-in循环来遍历字符串中的每一个字符:
for character in "Dog!"{
println(character) //要看到输出结果,点击眼睛右边的加号即可
}
通过为标明为Character类型的常量或者变量赋一个只有一个字符的值的方式来为字符初始化赋值。
let yenSign:Character = "¥"
字符串可以通过加法运算符+连接成一个新的字符串。
//+
let string1 = "hello"
let string2 = " there"
let char1:Character = "!"
var welcome = string1 + string2
var welcome1 = string1 + string2 + String(char1)//可以通过类型转换的方式。但是不能直接拼接Character
你也可以通过+=将一个字符串拼接到一个已经存在的字符串后面。
//+=
welcome += string2
你可以通过append方法将字符拼接到字符串后面。
//append
welcome.append(char1)
注意:苹果最开始允许+和+=来在字符串后面拼接字符,现在不允许了,改为append方法了!
字符串插值是一种全新的构建字符串的方式,可以在其中包含常量、变量、字面量和表达式。您插入的字符串字面量的每一项都被包裹在以反斜线为前缀的圆括号中:
let multiplier = 3
var yenUnit:Character = "$"
let message = "\(multiplier) times 2.5 is \(Double(multiplier)*2.5) \(yenUnit)"
注意:您插值字符串中写在括号中的表达式不能包含非转义双引号 (") 和反斜杠 (\),并且不能包含回车或换行符。
Swift 的字符串和字符类型是完全兼容 Unicode 的。
通过调用全局 countElements 函数,并将字符串作为参数进行传递可以获取该字符串的字符数量。
let unusualMenagerice = "Dog ,Snail "
println("unusualMenagerice has \(countElements(unusualMenagerice)) characters.")
注意:由于Swift使用了扩展字形集,所以修改字符串,不一定会影响它的字符数量。
var word = "cafe"
println("the number of characters in \(word) is \(countElements(word))") //4
word += "\u{301}" //café
println("the number of characters in \(word) is \(countElements(word))") //4
注意:
1.不同的 Unicode 字符以及相同 Unicode 字符的不同表示方式可能需要不同数量的内存空间来存储,所以Swift 中的字符在一个字符串中表示并不一定占用相同的内存空间。因此,字符串的长度不得不通过迭代字符串中每一个字符的长度来进行计算。如果您正在处理一个长字符串,需要注意 countElements 函数必须遍历字符串中的字符,以精准计算字符串的长度。
2.另外需要注意的是通过 countElements 返回的字符数量并不总是与包含相同字符的 NSString 的 length 属性相同。NSString 的 length 属性是基于利用 UTF-16 表示的十六位code units数目,而不是基于 Unicode 字符。为了解决这个问题,NSString 的 length 属性在被 Swift的 String值访问时会被称为utf16count。
Swift 提供了三种方式来比较字符串的值:字符串相等,前缀相等和后缀相等。
如果两个字符串或者两个字符的扩展字形集完全一样,就认为是相等的。
扩展字形集只要他们的含义和外形一样就认为是相等的,即使它们的Unicode编码格式不一样。
let quotation = "we're a lot alike ,you and I."
let sameQuotation = "we're a lot alike ,you and I."
if quotation == sameQuotation{
println("These two strings are considered equal.")
}
//"Voulez-vous un café?" using LATIN SMALL LETTER E WITH ACUTE
let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"
//"Voulez-vous un caé" using LATIN SMALL LETTER E and COMBINING ACUTE ACCENT
let combinedEAcuteQuestion = "Voulez-vous un caf\u{65}\u{301}?"
if eAcuteQuestion == combinedEAcuteQuestion{
println("These two strings are considered equal.")
}
//结果,这两个字符串相等。它们有相同的含义和外形。
let latinCapitalLetterA:Character = "\u{41}"
let cyrillicCapitalLetterA:Character = "\u{0410}"
if latinCapitalLetterA != cyrillicCapitalLetterA{
println("These two characters are not qualivalent.")
}
//结果,这两个字符不相等。它们有相同的外形,但是不同语言中的A,含义不一样。
注意:Swift的字符串和字符比较对不同语言环境不敏感。
通过调用字符串的 hasPrefix/hasSuffix 方法来检查字符串是否拥有特定前缀/后缀。两个方法均需要以字符串作为参数传入并返回 Boolean 值。两个方法均执行基本字符串和前缀/后缀字符串之间逐个字符的比较操作。
let romeoAndJuliet = [
"Act 1 Scene 1: Verona, A public place",
"Act 1 Scene 2: Capulet's mansion",
"Act 1 Scene 3: A room in Capulet's mansion",
"Act 1 Scene 4: A street outside Capulet's mansion",
"Act 1 Scene 5: The Great Hall in Capulet's mansion",
"Act 2 Scene 1: Outside Capulet's mansion",
"Act 2 Scene 2: Capulet's orchard",
"Act 2 Scene 3: Outside Friar Lawrence's cell",
"Act 2 Scene 4: A street in Verona",
"Act 2 Scene 5: Capulet's mansion",
"Act 2 Scene 6: Friar Lawrence's cell"
]
var act1SceneCount = 0
for scene in romeoAndJuliet{
if scene.hasPrefix("Act 1"){
++act1SceneCount
}
}
println("There are \(act1SceneCount) scenes in Act 1")
// prints "There are 5 scenes in Act 1"
var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
if scene.hasSuffix("Capulet's mansion") {
++mansionCount
} else if scene.hasSuffix("Friar Lawrence's cell") {
++cellCount
}
}
println("\(mansionCount) mansion scenes; \(cellCount) cell scenes")
// prints "6 mansion scenes; 2 cell scenes"
前缀/后缀相等,跟OC里面是一样的用法。
跟OC里面一样的用法:
var normalStr = "HELLO swift"
var lowerStr = normalStr.lowercaseString
var upperStr = normalStr.uppercaseString
Swift 提供了几种不同的方式来访问字符串的 Unicode 表示。您可以利用 for-in 来对字符串进行遍历,从而以 Unicode 字符的方式访问每一个字符值。
另外,能够以其他三种 Unicode 兼容的方式访问字符串的值:
1.UTF-8 代码单元集合 (利用字符串的 utf8 属性进行访问)
2.UTF-16 代码单元集合 (利用字符串的 utf16 属性进行访问)
3.21位的 Unicode 标量值集合 (利用字符串的 unicodeScalars 属性进行访问)
let dogString = "Dog!!"
for codeUnit in dogString.utf8{
println("\(codeUnit)")
}
for codeUnit in dogString.utf16{
println("\(codeUnit)")
}
for codeUnit in dogString.unicodeScalars{
println("\(codeUnit)")
}
这一章介绍了Swift语言中的字符串和字符的基本操作和一些概念。跟Cocoa的NSString做了无缝对接,但是也是有一定区别的。
1.字符串和字符的初始化方法变了。通过“”和String()创建的空字符串的是相等的。
2.Swift对变量和常量做了统一,所以在Swift中一个字符串是否可变,取决于它是let定义的还是var定义的,而不是OC中的NSMutableString。
3.Swift中的字符串变成了值类型,而OC中的字符串是引用类型。
4.Swift中通过+和+=来连接字符串,通过append()来连接字符,非常方便。
5.Swift中通过 \() 进行字符串插值也变得很方便了。
6.Swift中的字符串比较可以直接用==和!=而不是OC中的isEqualToString()方法了,想想也是,因为字符串变成了值类型了嘛,在OC中的值类型,咱也是通过==和!=来比较的。至于前缀/后缀相等、字符串转大小写,跟OC没啥差别。
参考:
1.The Swift Programming Language
2.http://www.cocoachina.com/ios/20140606/8704.html
注意:以苹果官方的The Swift Programming Language文档为主!因为我发现苹果有时候会有一些小小的改动,比如 之前的版本中+和+=是可以连接字符和字符串的,现在的版本只允许连接字符串,连接字符得用append()方法。所以说,还是要时常关注苹果官方的文档更新。