IOS开发语言Swift入门连载---字符串和字符

字符串和字符

String是例如“hello, world”,“海贼王” 这样的有序的Character (字符)类型的值的集合,通过String 类型来表示。

  Swift的String 和Character 类型提供了一个快速的,兼容 Unicode 的方式来处理代码中的文本信息。 创建和操作字符串的语法与 C 语言中字符串操作相似,轻量并且易读。 字符串连接操作只需要简单地通过+号将两个字符串相连即可。 与 Swift 中其他值一样,能否更改字符串的值,取决于其被定义为常量还是变量。

  尽管语法简易,但String 类型是一种快速、现代化的字符串实现。 每一个字符串都是由独立编码的 Unicode 字符组成,并提供了以不同 Unicode 表示(representations)来访问这些字符的支持。

  可以在常量、变量、字面量和表达式中进行字符串插值操作,可以轻松创建用于展示、存储和打印的自定义字符串。

  注意:

  的String 类型与 Foundation NSString 类进行了无缝桥接。如果您利用 Cocoa 或 Cocoa Touch 中的 Foundation 框架进行工作。所有NSString API 都可以调用您创建的任意String 类型的值。除此之外,还可以使用本章介绍的String 特性。您也可以在任意要求传入NSString 实例作为参数的 API 中使用String 类型的值作为替代。 更多关于在 Foundation 和 Cocoa 中使用String 的信息请查看 Using Swift with Cocoa and Objective-C。

  

字符串字面量(String Literals)

  您可以在您的代码中包含一段预定义的字符串值作为字符串字面量。 字符串字面量是由双引号 (“”) 包裹着的具有固定顺序的文本字符集。

  字符串字面量可以用于为常量和变量提供初始值。

let someString = "Some string literal value"

  注意:

  someString变量通过字符串字面量进行初始化,Swift 因此推断该变量为String 类型。

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

  转义字符\0 (空字符)、\ (反斜线)、\t (水平制表符)、\n (换行符)、\r (回车符)、\” (双引号)、\’ (单引号)。

  单字节 Unicode 标量,写成\xnn ,其中nn 为两位十六进制数。

  双字节 Unicode 标量,写成\unnnn ,其中nnnn 为四位十六进制数。

  四字节 Unicode 标量,写成\Unnnnnnnn ,其中nnnnnnnn 为八位十六进制数。

  下面的代码为各种特殊字符的使用示例。 wiseWords 常量包含了两个转移特殊字符 (双括号); dollarSign 、blackHeart 和sparklingHeart 常量演示了三种不同格式的 Unicode 标量:

let wiseWords = "\"我是要成为海贼王的男人\" - 路飞"
// "我是要成为海贼王的男人" - 路飞
let dollarSign = "\x24"             // $,  Unicode 标量 U+0024
let blackHeart = "\u2665"           // ,  Unicode 标量 U+2665
let sparklingHeart = "\U0001F496"  // , Unicode 标量 U+1F496

初始化空字符串

  为了构造一个很长的字符串,可以创建一个空字符串作为初始值。 可以将空的字符串字面量赋值给变量,也可以初始化一个新的String 实例:

var emptyString = ""               // 空字符串字面量
var anotherEmptyString = String()  // 初始化 String 实例
// 两个字符串均为空并等价。

  您可以通过检查其Boolean 类型的isEmpty 属性来判断该字符串是否为空:

if emptyString.isEmpty {
    println("什么都没有")
}
// 打印输出:"什么都没有"

字符串可变性

  您可以通过将一个特定字符串分配给一个变量来对其进行修改,或者分配给一个常量来保证其不会被修改:

var variableString = "Horse"
variableString += " and carriage"
// variableString 现在为 "Horse and carriage"
let constantString = "Highlander"
constantString += " and another Highlander"
// 这会报告一个编译错误 (compile-time error) - 常量不可以被修改。

  注意:

  在 Objective-C 和 Cocoa 中,您通过选择两个不同的类(NSString 和NSMutableString )来指定该字符串是否可以被修改,Swift 中的字符串是否可以修改仅通过定义的是变量还是常量来决定,实现了多种类型可变性操作的统一。

  字符串是值类型(Strings Are Value Types)

  Swift的String 类型是值类型。 如果您创建了一个新的字符串,那么当其进行常量、变量赋值操作或在函数/方法中传递时,会进行值拷贝。 任何情况下,都会对已有字符串值创建新副本,并对该新副本进行传递或赋值操作。 值类型在 结构体和枚举是值类型 中进行了说明。

  注意:

  与 Cocoa 中的NSString 不同,当您在 Cocoa 中创建了一个NSString 实例,并将其传递给一个函数/方法,或者赋值给一个变量,您传递或赋值的是该NSString 实例的一个引用,除非您特别要求进行值拷贝,否则字符串不会生成新的副本来进行赋值操作。

  默认字符串拷贝的方式保证了在函数/方法中传递的是字符串的值。 很明显无论该值来自于哪里,都是您独自拥有的。 您可以放心您传递的字符串本身不会被更改。

  在实际编译时,Swift 编译器会优化字符串的使用,使实际的复制只发生在绝对必要的情况下,这意味着您将字符串作为值类型的同时可以获得极高的性能。

  使用字符(Working with Characters)

  的String 类型表示特定序列的Character (字符) 类型值的集合。 每一个字符值代表一个 Unicode 字符。 您可利用for-in 循环来遍历字符串中的每一个字符:

for character in "Dog!" {
    println(character)
}

  for-in循环在 For Loops 中进行了详细描述。

  另外,通过标明一个Character 类型注解并通过字符字面量进行赋值,可以建立一个独立的字符常量或变量:

let yenSign: Character = "¥"

计算字符数量

  通过调用全局countElements 函数,并将字符串作为参数进行传递,可以获取该字符串的字符数量。

let unusualMenagerie = "Koala , Snail , Penguin , Dromedary "
println("unusualMenagerie has \(countElements(unusualMenagerie)) characters")
// 打印输出:"unusualMenagerie has 40 characters"

  注意:

  不同的 Unicode 字符以及相同 Unicode 字符的不同表示方式可能需要不同数量的内存空间来存储。所以 Swift 中的字符在一个字符串中并不一定占用相同的内存空间。因此字符串的长度不得不通过迭代字符串中每一个字符的长度来进行计算。如果您正在处理一个长字符串,需要注意countElements 函数必须遍历字符串中的字符以精准计算字符串的长度。 另外需要注意的是通过countElements 返回的字符数量并不总是与包含相同字符的NSString 的length 属性相同。NSString 的length 属性是基于利用 UTF-16 表示的十六位代码单元数字,而不是基于 Unicode 字符。为了解决这个问题,NSString 的length 属性在被 Swift 的String 访问时会成为utf16count 。

  

连接字符串和字符

  字符串和字符的值可以通过加法运算符(+)相加在一起并创建一个新的字符串值:

let string1 = "hello"
let string2 = " there"
let character1: Character = "!"
let character2: Character = "?"

let stringPlusCharacter = string1 + character1        // 等于 "hello!"
let stringPlusString = string1 + string2              // 等于 "hello there"
let characterPlusString = character1 + string1        // 等于 "!hello"
let characterPlusCharacter = character1 + character2  // 等于 "!?"

  您也可以通过加法赋值运算符 (+= ) 将一个字符串或者字符添加到一个已经存在字符串变量上:

var instruction = "look over"
instruction += string2
// instruction 现在等于 "look over there"

var welcome = "good morning"
welcome += character1
// welcome 现在等于 "good morning!"

  注意:

  您不能将一个字符串或者字符添加到一个已经存在的字符变量上,因为字符变量只能包含一个字符。

  

字符串插值

  字符串插值是一种构建新字符串的方式,可以在其中包含常量、变量、字面量和表达式。 您插入的字符串字面量的每一项都被包裹在以反斜线为前缀的圆括号中:

let multiplier = 3
let message = "\(multiplier) 乘以 2.5 是 \(Double(multiplier) * 2.5)"
// message 是 "3 乘以 2.5 是 7.5"

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

  的值也作为字符串中后面表达式的一部分。 该表达式计算Double(multiplier) * 2.5 的值并将结果 (7.5) 插入到字符串中。 在这个例子中,表达式写为(Double(multiplier) * 2.5) 并包含在字符串字面量中。

  注意:

  插值字符串中写在括号中的表达式不能包含非转义双引号 (” ) 和反斜杠 (\ ),并且不能包含回车或换行符。

  

比较字符串

  提供了三种方式来比较字符串的值:字符串相等、前缀相等和后缀相等。

  字符串相等

  如果两个字符串以同一顺序包含完全相同的字符,则认为两者字符串相等:

let quotation = "我们是一样一样滴."
let sameQuotation = "我们是一样一样滴."
if quotation == sameQuotation {
    println("这两个字符串被认为是相同的")
}
// 打印输出:"这两个字符串被认为是相同的"

  前缀/后缀相等

  通过调用字符串的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"
]

  您可以利用hasPrefix 方法来计算话剧中第一幕的场景数:

var act1SceneCount = 0
for scene in romeoAndJuliet {
    if scene.hasPrefix("Act 1 ") {
        ++act1SceneCount
    }
}
println("There are \(act1SceneCount) scenes in Act 1")
// 打印输出:"There are 5 scenes in Act 1"

  相似地,您可以用hasSuffix 方法来计算发生在不同地方的场景数:

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")
// 打印输出:"6 mansion scenes; 2 cell scenes”

大写和小写字符串(Uppercase and Lowercase Strings)

  您可以通过字符串的uppercaseString 和lowercaseString 属性来访问大写/小写版本的字符串。

let normal = "Could you help me, please?"
let shouty = normal.uppercaseString
// shouty  "COULD YOU HELP ME, PLEASE?"
let whispered = normal.lowercaseString
// whispered  "could you help me, please?"

Unicode

  Unicode是一个国际标准,用于文本的编码和表示。 它使您可以用标准格式表示来自任意语言几乎所有的字符,并能够对文本文件或网页这样的外部资源中的字符进行读写操作。

  Swift的字符串和字符类型是完全兼容 Unicode 标准的,它支持如下所述的一系列不同的 Unicode 编码。

  Unicode术语(Unicode Terminology)

  中每一个字符都可以被解释为一个或多个 unicode 标量。 字符的 unicode 标量是一个唯一的21位数字(和名称),例如U+0061 表示小写的拉丁字母A (“a”),U+1F425 表示小鸡表情

  当 Unicode 字符串被写进文本文件或其他存储结构当中,这些 unicode 标量将会按照 Unicode 定义的集中格式之一进行编码。其包括UTF-8 (以8位代码单元进行编码) 和UTF-16 (以16位代码单元进行编码)。

  字符串的 Unicode 表示(Unicode Representations of Strings)

  Swift提供了几种不同的方式来访问字符串的 Unicode 表示。

  您可以利用for-in 来对字符串进行遍历,从而以 Unicode 字符的方式访问每一个字符值。 该过程在 使用字符 中进行了描述。

  另外,能够以其他三种 Unicode 兼容的方式访问字符串的值:

  代码单元集合 (利用字符串的utf8 属性进行访问

  代码单元集合 (利用字符串的utf16 属性进行访问

  位的 Unicode 标量值集合 (利用字符串的unicodeScalars 属性进行访问

  下面由Dog“! 和??(DOG FACE ,Unicode 标量为U+1F436 )组成的字符串中的每一个字符代表着一种不同的表示:

let dogString = "Dog!"

  UTF-8

  您可以通过遍历字符串的utf8 属性来访问它的 UTF-8 表示。 其为UTF8View 类型的属性,UTF8View 是无符号8位 (UInt8 ) 值的集合,每一个UInt8 值都是一个字符的 UInt8 表示:

for codeUnit in dogString.utf8 {
    print("\(codeUnit) ")
}
print("\n")
// 68 111 103 33 240 159 144 182

  上面的例子中,前四个10进制代码单元值 (68, 111, 103, 33) 代表了字符D o g和!,它们的 UTF-8 表示与 ASCII 表示相同。 后四个代码单元值 (240, 159, 144, 182) 是DOG FACE的4字节 UTF-8 表示。

  UTF-16

  您可以通过遍历字符串的utf16 属性来访问它的UTF-16 表示。 其为UTF16View 类型的属性,UTF16View 是无符号16位 (UInt16 ) 值的集合,每一个UInt16 都是一个字符的 UTF-16表示:

for codeUnit in dogString.utf16 {
    print("\(codeUnit) ")
}
print("\n")
// 68 111 103 33 55357 56374

  同样,前四个代码单元值 (68, 111, 103, 33) 代表了字符D o g 和! ,它们的 UTF-16 代码单元和 UTF-8 完全相同。

  第五和第六个代码单元值 (55357 和 56374) 是DOG FACE 字符的UTF-16 表示。 第一个值为U+D83D (十进制值为 55357),第二个值为U+DC36 (十进制值为 56374)。

  Unicode标量

  您可以通过遍历字符串的unicodeScalars 属性来访问它的 Unicode 标量表示。 其为UnicodeScalarView 类型的属性, UnicodeScalarView 是UnicodeScalar 的集合。 UnicodeScalar 是21位的 Unicode 代码点。

  每一个UnicodeScalar 拥有一个值属性,可以返回对应的21位数值,用UInt32 来表示。

for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ")
}
print("\n")
// 68 111 103 33 128054

  同样,前四个代码单元值 (68, 111, 103, 33) 代表了字符D o g 和! 。 第五位数值,128054,是一个十六进制1F436的十进制表示。 其等同于DOG FACE 的Unicode 标量 U+1F436。

  作为查询字符值属性的一种替代方法,每个UnicodeScalar 值也可以用来构建一个新的字符串值,比如在字符串插值中使用:

for scalar in dogString.unicodeScalars {
    println("\(scalar) ")
}
时间: 2024-08-13 12:23:22

IOS开发语言Swift入门连载---字符串和字符的相关文章

IOS开发语言Swift入门连载---类和结构体

IOS开发语言Swift入门连载-类和结构体 类和结构体是人们构建代码所用的一种通用且灵活的构造体.为了在类和结构体中实现各种功能,我们必须要严格按照常量.变量以及函数所规定的语法规则来定义属性和添加方法. 与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意: 通常一个类 的实例被称为对象 .然而在Swift 中,类和结构体的关系要比在其他语言中更加的密切,本

IOS开发语言Swift入门连载---属性

IOS开发语言Swift入门连载-属性 属性将值跟特定的类.结构或枚举关联.存储属性存储常量或变量作为实例的一部分,计算属性计算(而不是存储)一个值.计算属性可以用于类.结构体和枚举里,存储属性只能用于类和结构体. 存储属性和计算属性通常用于特定类型的实例,但是,属性也可以直接用于类型本身,这种属性称为类型属性. 另外,还可以定义属性监视器来监控属性值的变化,以此来触发一个自定义的操作.属性监视器可以添加到自己写的存储属性上,也可以添加到从父类继承的属性上. 存储属性 简单来说,一个存储属性就是

IOS开发语言Swift入门连载---闭包

IOS开发语言Swift入门连载-闭包 闭包是自包含的函数代码块,可以在代码中被传递和使用. Swift 中的闭包与 C 和 Objective-C 中的代码块(blocks)以及其他一些编程语言中的 lambdas 函数比较相似. 闭包可以捕获和存储其所在上下文中任意常量和变量的引用. 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包.Swift 会为您管理在捕获过程中涉及到的所有内存操作. 注意: 如果您不熟悉捕获(capturing)这个概念也不用担心,您可以在 值捕获 章节对其进行详细了

IOS开发语言Swift入门连载---枚举

IOS开发语言Swift入门连载-枚举 枚举定义了一个通用类型的一组相关的值,使你可以在你的代码中以一个安全的方式来使用这些值. 如果你熟悉 C 语言,你就会知道,在 C 语言中枚举指定相关名称为一组整型值.Swift 中的枚举更加灵活,不必给每一个枚举成员提供一个值.如果一个值(被认为是"原始"值)被提供给每个枚举成员,则该值可以是一个字符串,一个字符,或是一个整型值或浮点值. 此外,枚举成员可以指定任何类型的相关值存储到枚举成员值中,就像其他语言中的联合体(unions)和变体(v

IOS开发语言Swift入门连载---函数

IOS开发语言Swift入门连载-函数 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被"调用". Swift统一的函数语法足够灵活,可以用来表示任何函数,包括从最简单的没有参数名字的 C 风格函数,到复杂的带局部和外部参数名的 Objective-C 风格函数.参数可以提供默认值,以简化函数调用.参数也可以既当做传入参数,也当做传出参数,也就是说,一旦函数执行结束,传入的参数值可以被修改. 在 Swift

IOS开发语言Swift入门连载---泛型

IOS开发语言Swift入门连载-泛型 泛型代码可以让你写出根据自我需求定义.适用于任何类型的,灵活且可重用的函数和类型.它的可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图. 泛型是 Swift 强大特征中的其中一个,许多 Swift 标准库是通过泛型代码构建出来的.事实上,泛型的使用贯穿了整本语言手册,只是你没有发现而已.例如,Swift 的数组和字典类型都是泛型集.你可以创建一个Int 数组,也可创建一个String 数组,或者甚至于可以是任何其他 Swift 的类型数据数组

IOS开发语言Swift入门连载---集合类型

IOS开发语言Swift入门连载-集合类型 Swift语言提供经典的数组和字典两种集合类型来存储集合数据.数组用来按顺序存储相同类型的数据.字典虽然无序存储相同类型数据值但是需要由独有的标识符引用和寻址(就是键值对). Swift语言里的数组和字典中存储的数据值类型必须明确. 这意味着我们不能把不正确的数据类型插入其中. 同时这也说明我们完全可以对获取出的值类型非常自信. Swift 对显式类型集合的使用确保了我们的代码对工作所需要的类型非常清楚,也让我们在开发中可以早早地找到任何的类型不匹配错

IOS开发语言Swift入门连载---控制流

IOS开发语言Swift入门连载-控制流 Swift提供了类似 C 语言的流程控制结构,包括可以多次执行任务的for 和while 循环,基于特定条件选择执行不同代码分支的if 和switch 语句,还有控制流程跳转到其他代码的break 和continue 语句. 除了 C 语言里面传统的 for 条件递增(for-condition-increment )循环,Swift 还增加了for-in 循环,用来更简单地遍历数组(array),字典(dictionary),区间(range),字符串

IOS开发语言Swift入门连载---可选链

IOS开发语言Swift入门连载-可选链 可选链(Optional Chaining) 是一种可以请求和调用属性.方法及下标脚本的过程,它的可选性体现于请求或调用的目标当前可能为空(nil ).如果可选的目标有值,那么调用就会成功:相反,如果选择的目标为空(nil ),则这种调用将返回空(nil ).多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(nil )将导致整个链失效. 注意: 的可选链和 Objective-C 中的消息为空有些相像,但是 Swift 可以使用在任意类型中