Swift的字符串类型String,跟OC的NSString,在API设计上还是有较大差异的。
一、字符串内容操作
1.1. 字符串的拼接
示例代码:
// 空字符串
var emptyStr1 = ""
var emptyStr2 = String()
var str: String = "1"
// 拼接
str.append("_2")
// 重载运算符+
str = str + "_3"
// 重载运算符+=
str += "_4"
// \()插值
str = "\(str)_5"
// 长度
print(str,str.count) // 输出:1_2_3_4_5 9
print(str.hasPrefix("1")) // 输出:true
print(str.hasSuffix("5")) // 输出:true
1.2. String的插入和删除
OC中字符串分为可变和不可变,Swift中的字符串就是可变的。
Swift字符串有startIndex和endIndex两个属性,用来表示字符串索引位置的,但是这两个属性都不是Int类型,他们都是String.Index类型。startIndex表示字符串第一个位置,endIndex总是比最后一个位置大(注意不是最后一个字符的位置)。
示例代码:
var str = "1_2"
// 拼接字符
str.insert("_", at: str.endIndex) // 1_2_
// 拼接字符串
str.insert(contentsOf: "3_4", at: str.endIndex) // 1_2_3_4
// 开始索引之后的位置插入
str.insert(contentsOf: "666", at: str.index(after: str.startIndex)) // 1666_2_3_4
// 结束索引之前的位置插入
str.insert(contentsOf: "888", at: str.index(before: str.endIndex)) // 1666_2_3_8884
// 按照索引位置偏移量插入
str.insert(contentsOf: "hello", at: str.index(str.startIndex, offsetBy: 4)) // 1666hello_2_3_8884
// 按照索引位置删除
str.remove(at: str.firstIndex(of: "1")!) // 666hello_2_3_8884
// 遍历每个字符,返回true删除,否则不删
str.removeAll() {
$0 == "6" } // hello_2_3_8884
// 按照字符串范围删除
var range = str.index(str.endIndex, offsetBy: -4)..<str.index(before: str.endIndex)
str.removeSubrange(range) // hello_2_3_4
二、Substring
String可以通过下标、prefix、suffix等截取子串,子串类型不是String,而是Substring(如果要使用String的所有函数和属性,可以把Substring转换为String)。
示例代码:
var str = "1_2_3_4_5"
var substr1 = str.prefix(3) // 1_2
var substr2 = str.suffix(3) // 4_5
var range = str.startIndex..<str.index(str.startIndex, offsetBy: 3)
var substr3 = str[range] // 1_2
print(substr3.base) // 最初的String 1_2_3_4_5
var str2 = String(substr3) // Substring -> String
Substring和它的base,共享字符串数据。
Substring发生修改或者转为String时,会重新分配新的内存存储字符串数据。
官方示例:
let greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
// Convert the result to a String for long-term storage.
let newString = String(beginning)

三、String与Character
示例代码:
for c in "idbeny" {
print(c)
}
/*
输出:
i
d
b
e
n
y
*/
var str = "idbeny"
var c = str[str.startIndex]
print(c) // 输出:i
示例中c是Character类型,因为传入的是单个位置。如果下标传入的是一个范围,就是Substring类型。
四、String相关的协议
4.1. BidirectionalCollection协议
String扩展遵守StringProtocol协议,而StringProtocol协议遵守BidirectionalCollection协议,BidirectionalCollectionx协议有startIndex、endIndex属性,index方法。
String和Array都遵守了这个协议。只不过Array指定了startIndex、endIndex等属性是Int类型,String相关属性时String.Index类型(内部实现原理是BidirectionalCollection协议的关联类型)。
4.2. RangeReplaceableCollection协议
RangeReplaceableCollection协议中有append、insert、remove方法,String、Array都遵守了这个协议。
Dictionary、Set也有实现上述协议中声明的一些方法,只是并没有遵守上述协议。
五、多行String
- 使用三个双引号
"""内容"""把内容括起来就可以实现多行String。
示例代码:
let str = """
第一行
第二行
第三行
第四行
第五行
"""
print(str)
/*
输出:
第一行
第二行
第三行
第四行
第五行
*/
- 如果要显示3引号,至少转义1个引号。
示例代码:
let str = """
Escaping the first quotation mark \"""
Escaping all three quotation marks \"\"\"
"""
print(str)
/*
输出:
Escaping the first quotation mark """
Escaping all three quotation marks """
*/
- 缩进以最后一个结尾引号为对齐线。
示例代码一:
let str = """
This string starts with a line break.
It also ends with a line break.
"""
print(str)
/*
输出:
This string starts with a line break.
It also ends with a line break.
*/
示例代码二:
let str = """
This line doesn't begin with whitespace.
This line begins with four spaces.
This line doesn't begin with whitespace.
"""
print(str)
/*
输出:
This line doesn't begin with whitespace.
This line begins with four spaces.
This line doesn't begin with whitespace.
*/

- 下面的字符串是等价的。
示例代码三:
let str1 = "These are the same."
print(str1)
/*
输出:
These are the same.
*/
let str2 = """
These are the same.
"""
print(str1)
/*
输出:
These are the same.
*/
let str3 = """
These are the same.
"""
print(str1)
/*
输出:
These are the same.
*/
六、String与NSString
String与NSString之间可以随时随地桥接转换。
如果你觉得String的API过于复杂难用,可以考虑将String转为NSString。
示例代码:
var str1: String = "jack"
var str2: NSString = "rose"
var str3 = str1 as NSString
var str4 = str2 as String
var str5 = str3.substring(with: NSRange(location: 0, length: 2))
print(str5) // 输出:ja
注意:
String与NSString之间相互转换是有转换代价的(调用函数),但是可以忽略不计。String不能桥接转换成NSMutableString。
- 比较字符串内容是否等价。
String使用==运算符NSString使用isEqual方法,也可以使用==运算符(本质还是调用了isEqual方法)
Swift和OC桥接转换表:

String转换为NSMutableString是可以的(注意是转换、不是桥接):
var str1: String = "jack"
var str2 = NSMutableString(string: str1)

转载:https://blog.csdn.net/yangbenben8866/article/details/116448088