可能很多同学有以下疑问。 我来回答以下。
问:为什么Swift中的字符串在进行切片操作的时候不能像Python或者其他语言,使用数字下标?而使用String.Index这个结构体
回答:
在Unicode中, 一个我们可以看得见的单一字符,有可能并不是一个Unicdoe标量。例如【é】这个字符。它可以是一个Unicode标量【\u{e9}】, 也有可能是二个Unicode标量【\u{65}】和【\u{301}】组合的结果。上述2个标量的情况在Swift计算中,仍然会被认为是1个字符。
我们可以认为Swift中的charactor类型是一种扩展的类型。其由1个或者多个Unicode标量组成。不再是我们认为的1对1的对应关系。character是一个Unicode标量序列。
正因如此。一个字符串的长度,或者随机访问,需要遍历这个字符串的char序列进行Combine计算后才能得到。所以Swift用String.Index这个结构体来抽象String中的char的index。Swift也就不能提供下标为数字的随机访问。而且仅提供Start和End2个默认的String.index。 这是因为它只能告诉你最开始的和最后的, 因为其他的都需要去从前或者从后进行遍历。在需要的时候进行Unicode变量组合计算后才能真正获知。
那有没有方法我使用数字字面量来进行切片呢?
答案是可以的。
如下:
extension String {
public subscript(intRange: Range<Int>) -> String {
let start = self.index(startIndex, offsetBy: intRange.startIndex)
let end = self.index(startIndex, offsetBy: intRange.endIndex)
let range = start..<end
return String(self[range])
}
}
我们使用扩展。来扩展String 类型的一个下标操作。传入的Range是Int类型的。
这个解决方法里体现了Swift的面向协议思想、扩展特性、以及自定义操作符等等知识点。所以。Swift的学习门槛还是挺高的。 即使在讲解基础知识的时候。也融进去了Swift的高级编程特性、或者思想。
学习的时候可以先把为什么记下来。 待学习完其他章节后,再回过头来自己尝试解决这些为什么。
展开