为什么带范围的swift子字符串需要特殊类型的范围

为什么带范围的swift子字符串需要特殊类型的范围,swift,string,substring,Swift,String,Substring,考虑使用此函数构建随机字符字符串: func makeToken(length: Int) -> String { let chars: String = "abcdefghijklmnopqrstuvwxyz0123456789!?@#$%ABCDEFGHIJKLMNOPQRSTUVWXYZ" var result: String = "" for _ in 0..<length { let idx = Int(arc4random_un

考虑使用此函数构建随机字符字符串:

func makeToken(length: Int) -> String {
    let chars: String = "abcdefghijklmnopqrstuvwxyz0123456789!?@#$%ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    var result: String = ""
    for _ in 0..<length {
        let idx =  Int(arc4random_uniform(UInt32(chars.characters.count)))
        let idxEnd = idx + 1
        let range: Range = idx..<idxEnd
        let char = chars.substring(with: range)
        result += char
    }
    return result
}
我很困惑,为什么我不能简单地提供一个包含2个整数的
范围
,为什么它会让我走上一条迂回的道路,创建一个
范围

因此,我必须将
范围
创建更改为非常复杂的方式:

let idx =  Int(arc4random_uniform(UInt32(chars.characters.count)))
let start = chars.index(chars.startIndex, offsetBy: idx)
let end = chars.index(chars.startIndex, offsetBy: idx + 1)
let range: Range = start..<end
设idx=Int(arc4random_统一(UInt32(chars.characters.count)))
let start=chars.index(chars.startIndex,offsetBy:idx)
let end=chars.index(chars.startIndex,offsetBy:idx+1)

让range:range=start..我建议将您的
字符串
转换为
[字符]
,这样您就可以使用
Int
轻松索引它:

func makeToken(length: Int) -> String {
    let chars = Array("abcdefghijklmnopqrstuvwxyz0123456789!?@#$%ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters)

    var result = ""
    for _ in 0..<length {
        let idx = Int(arc4random_uniform(UInt32(chars.count)))
        result += String(chars[idx])
    }
    return result
}
func makeToken(长度:Int)->String{
设chars=Array(“abcdefghijklmnopqrstuvwxyz123456789!?@#$%abcdefghijklmnopqrstuvxyz.characters)
var result=“”

对于uu0..Swift非常小心地提供完全符合Unicode的、类型安全的
字符串
抽象

在任意Unicode字符串中为给定的
字符
编制索引绝非易事。每个
字符
都是一个或多个Unicode标量的序列(组合时)生成一个人类可读的字符。特别是,将所有这些复杂性隐藏在一个简单的基于
Int
的索引方案背后,可能会导致程序员错误的性能心理模型

话虽如此,您始终可以将字符串转换为
数组
一次,以方便(快速)索引。例如:

let chars: String = "abcdefghijklmnop"
var charsArray = Array(chars.characters)
...
let resultingString = String(charsArray)

因为字符并不是那么简单。它们占用的内存量并不相同。请参阅文档中的字符串部分。我想您错过了字符串文本末尾的
。字符
。在Swift 4中,您可以删除
。字符
。在发布之前,我在Xcode和Linux上对此进行了测试。@Inorganik BTW,仅使用
数组(“abc”)
在Swift 4中可以很好地工作,因为改进的
字符串
类;)为什么Swift甚至需要计算标量序列的复杂性?为什么我会关心这一点?我个人更喜欢javascript的方式-它隐藏标量混乱,因为我永远不需要碰它,99.9%的用户也不会碰它us@inorganik他们非常努力rd是Unicode正确的,默认情况下是经得起未来考验的。事实上,Swift是一个向我们隐藏标量“混乱”的人;)要了解我的意思,请在28:00左右。他们提供了一些很好的例子,说明了为什么这在实践中很重要……谢谢Paulo,我会检查它。
let chars: String = "abcdefghijklmnop"
var charsArray = Array(chars.characters)
...
let resultingString = String(charsArray)