字符串和字符

目录

引入

字符串是一系列的字符, 使用 String 类型表示。Swift的字符串类型是一种快速且标准的实现。 每个字符串都由独立于编码的 Unicode 字符组成, 并支持以各种 Unicode 表示形式访问这些字符。

字符串字面量

字符串字面量是由双引号包围的字符序列。

let name = "hzclog"

多行字符串

如果需要一个跨多行的字符串, 可以使用多行字符串字面量: 由三个双引号包围的字符序列。

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

如果在多行字符串中包含换行符, 换行符也会出现在字符串的值中。

运行结果

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

特殊字符

字符串中可以包含下面的特殊字符

  • 转义特殊字符 \0(空字符)、 \\(反斜线)、 \t(水平制表符)、 \n(换行符)、 \r(回车符)、 \“(双引号)和 \‘(单引号)
  • 写作 \u{n} 格式的Unicode字符值。

比如下面的示例:

let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\u{24}"        // $
let blackHeart = "\u{2665}"      // ♥
let sparklingHeart = "\u{1F496}" // 💖

扩展分隔符

将字符串放在扩展分隔符中, 就可以直接包含特殊字符了, 这样不会产生特殊效果。

let wiseWords = #""Imagination is more important than knowledge" - Einstein"#
// "Imagination is more important than knowledge" - Einstein
let dollarSign = #"\u{24}"#        // \u{24}

初始化空字符串

可以使用字面量或者初始化器创建字符串实例。

var emptyString = ""
var anotherEmptyString = String() 

字符串的 isEmpty 属性判断字符串是否为空。

var emptyString = ""
print(emptyString.isEmpty) // true

字符串的可变性

字符串是否可变, 取决于将字符串赋值给变量还是常量。

var str1 = "hello"
str1 += "world"
print(str1) // helloworld

let str2 = "come"
str2 += "in" // 报错:'str2' is a 'let' constant
print(str2)

字符串是值类型

Swift中的字符串类型是值类型

如果创建一个字符串值, 将其赋值给常量或者变量时, 会复制该字符串值;

学习函数以后, 如果给函数传入字符串值, 也会复制, 即创建这个字符串的副本。

这样做的好处是: 当函数传入字符串值,或者将已有字符串赋值给新变量时, 我们可以随意操作它, 而不用担心会影响原来的值

拼接字符串(+)

上个章节我们已经见识过了,不再赘述。

字符串插值

字符串插值我们也学习过了,不过可以补充一点新内容。

let birth = 1991

// 插值输出
print("出生在:\(birth)年") // 出生在:1991年

// 想原样输出里面的文本,使用扩展分隔符
print(#"出生在:\(birth)年"#) // 出生在:\(birth)年

// 圆括号里面也不单纯只能是变量或常量,可以是一个表达式
print("年龄是:\(2024 - birth)岁") // 年龄是:33岁

字符计数

想要知道字符串中有多少个字符,可以使用 count 属性。

let message = "hello world"
print(message.count) // 11, 注意空格符也是字符

访问和修改字符串

字符串索引

每个字符串值都有关联的索引类型: String.Index, 它与字符串中每个字符串的位置相对应。

startIndex 属性访问字符串的第一个字符的位置。 endIndex 属性是字符串最后一个字符 后面的位置。 如果字符串为空, startIndexendIndex 就是相等的。

  • index(before:) 方法可以访问给定索引之前的索引。
  • index(after:) 方法可以访问给定索引之后的索引。
  • index(_:offsetBy:) 方法可以访问给定偏移位置的索引。

知道了索引以后, 可以通过语法 字符串[索引] 访问对应的字符。 用代码来瞧瞧。

let message = "hello world"

// 起始索引的字符
print(message[message.startIndex]) // h

// 起始位置之后的字符
print(message[message.index(after: message.startIndex)]) // e

// 最后一个字符
print(message[message.index(before: message.endIndex)]) // d

// 起始位置之后,偏移6个位置的字符
print(message[message.index(message.startIndex, offsetBy: 6)]) // w

访问范围以外的索引,就会触发运行错误。

let message = "hello world"

print(message[message.endIndex]) // 错误

插入和移除内容

在指定索引插入单个字符, 使用 insert(_:at:) 方法。

在指定索引插入另一个字符串内容, 使用 insert(contentsOf:at:) 方法。

var message = "hello world"

// 在字符串默认插入!
message.insert("!", at: message.endIndex)
print(message) // hello world!

let anotherMessage = "what?"

// 在字符串开头插入anotherMessage内容
message.insert(contentsOf: anotherMessage, at: message.startIndex)
print(message) // what?hello world!

要删除指定索引的单个字符, 使用 remove(at:) 方法。

要删除指定范围的子串, 使用 removeSubrange(_:) 方法。

var message = "hello hzclog!"

// 删除!
message.remove(at: message.index(before: message.endIndex))
print(message) // hello hzclog

// 创建索引范围(学习range以后,再过来看)
let range = message.index(message.endIndex, offsetBy: -7)..<message.endIndex
// 删除指定范围
message.removeSubrange(range)
print(message) // hello

子串

要从字符串中获取子串, 得到的结果是 Substring 的实例。 可以使用 String 将子串转换为字符串实例。

let message = "Hello, world!"

// firstIndex(of:) 获取给定字符在字符串的索引, 因为字符可能不存在,所以给一个后备值startIndex
let index = message.firstIndex(of: ",") ?? message.startIndex

// 通过索引范围获取子串
let beginning = message[..<index]

// 将子串转换成字符串使用
let newString = String(beginning)
print(newString) // Hello

子串的实例重复使用了原始字符串的部分内存, 这就意味着只要使用子串, 原始字符串就必须 存在于内存中。

为了子串的使用不受影响, 最好使用 String 转化新的字符串,拥有独立空间。

字符串和字符比较

Swift支持字符串和字符比较, 这种比较使用相对较少, 感兴趣可以看这里 Comparing Strings

下一章

本章学习了字符串和字符相关的内容, 下个章节中我们学习Swift中的集合类型。