以下所有示例都使用
var str = "Hello, playground"
Swift 4
弦乐在《Swift 4》中得到了相当大的改进.当你现在从一个字符串中得到一些子字符串时,你得到的是Substring
而不是String
.这是为什么?字符串是Swift中的值类型.这意味着如果你使用一个字符串来创建一个新的字符串,那么它必须被复制过来.这有利于 solidity (在你不知情的情况下,没有人会改变它),但对效率不利.
另一方面,子字符串是对其来源的原始字符串的引用.下面是一张来自documentation人的图片,说明了这一点.
无需复制,因此使用效率更高.然而,假设你从一个百万字符的字符串中得到了一个十个字符的子字符串.因为子字符串引用字符串,所以只要子字符串还在,系统就必须保持整个字符串.因此,无论何时操作完子字符串,都要将其转换为字符串.
let myString = String(mySubstring)
这将只复制子字符串,保存旧字符串的内存可以是reclaimed.子字符串(作为一种类型)应该是短暂的.
Swift 4的另一个重大改进是字符串是集合(再次).这意味着,无论对集合做什么,都可以对字符串做什么(使用下标、迭代字符、过滤器等).
下面的示例演示如何在Swift中获取子字符串.
Getting substrings
可以通过使用下标或许多其他方法(例如prefix
、suffix
、split
)从字符串中获取子字符串.不过,对于这个范围,仍然需要使用String.Index
而不是Int
索引.(如果需要帮助,请参阅my other answer.)
弦的开头
您可以使用下标(注意Swift 4单侧范围):
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello
或prefix
:
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello
甚至更简单:
let mySubstring = str.prefix(5) // Hello
结束
使用下标:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground
或suffix
:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground
甚至更简单:
let mySubstring = str.suffix(10) // playground
请注意,当使用suffix(from: index)
时,我必须使用-10
从末尾倒数.如果只使用suffix(x)
,这是不必要的,它只需要字符串的最后x
个字符.
一串
同样,我们只是在这里使用下标.
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
let mySubstring = str[range] // play
Converting Substring
to String
别忘了,当你准备好保存你的子字符串时,你应该把它转换成String
,这样旧字符串的内存就可以被清除了.
let myString = String(mySubstring)
Using an Int
index extension?
在阅读了空速和奥勒·贝格曼(Ole Begemann)的文章Strings in Swift 3之后,我很犹豫是否使用基于Int
的索引扩展.虽然在Swift 4中,字符串是集合,但Swift团队故意没有使用Int
个索引.现在仍然是String.Index
.这与由不同数量的Unicode代码点组成的快速字符有关.必须 for each 字符串唯一地计算实际索引.
我不得不说,我希望Swift团队能找到一种方法,在future 抽走String.Index
名球员.但在它们出现之前,我 Select 使用它们的API.它帮助我记住字符串操作不仅仅是简单的Int
索引查找.