Swift String Slice(Index OR Substring)

955 阅读1分钟

String Indices

每个字符串都有一个关联的index类型String.Index,它负责记录字符串里各个字符的位置。不能用整数下标来索引字符,因为字符串中的各个字符占用的内存空间不同,所以必须从字符串的头部或尾部迭代每一个字符以确定各个字符的具体位置。

Index Getter

// 第一个字符的位置
@inlinable public var startIndex: String.Index { get }
// 最后一个字符的后一个位置,空字string时startIndex==endIndex
@inlinable public var endIndex: String.Index { get }

Access Index

func index(after i: String.Index) -> String.Index
func index(before i: String.Index) -> String.Index
func index(_ i: String.Index, offsetBy n: String.IndexDistance) -> String.Index

Example

var str = "Hello, String"
print(str.startIndex) // Index(_rawBits: 1)
print(str.endIndex)   // Index(_rawBits: 851969)
print(str.count)      // 13

Inserting and Removing

Example

var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)  // "hello!"
// "hello String!"
welcome.insert(contentsOf: " String", at: welcome.index(before: welcome.endIndex)) 
// return "!", welcom="hello String"
welcome.remove(at: welcome.index(before: welcome.endIndex))

let range = welcome.index(welcome.endIndex, offsetBy: -7) ..< welcome.endIndex 
welcome.removeSubrange(range) // "hello"

Substrings

Substring的生成及内存优化

截取String后会生成一个Substring实例,Substring和String大部分操作方法都是相同的。substring可供短时间内使用,如果要长时间存储结果就要把Substring转换成String

  • substring复用了原始string的部分内存(String也有同样的优化,两个string共享内存,那么两个string就是相等的)
  • 这意味着共享内存的string或substring只有在被修改时才会进行内存拷贝
  • 综上所述,substring不适合长时间存储,因为substring使用了原始string的内存,只要substring还在使用,完整的原始string就必现保留再内存里,如下图所示。
  • String和Substring都遵守StringProtocol协议,所以可以很方便的使用string操作方法获取一个StringProtocol

image.png

Example

var greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex

let beginning = greeting[..<index]
let newString = String(beginning) // Convert the result to a String for long-term storage.

greeting.remove(at: greeting.startIndex)

print(greeting, beginning, newString)

result: ello, world! Hello Hello

Reference Swift Document - Strings and Characters