【发布时间】:2017-07-06 23:30:45
【问题描述】:
考虑用这个函数构建一串随机字符:
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
}
这会在 substring 方法上引发错误:
Cannot convert value of type 'Range<Int>' to expected argument
type 'Range<String.Index>' (aka 'Range<String.CharacterView.Index>')
我很困惑为什么我不能简单地提供一个带有 2 个整数的 Range,以及为什么它让我绕道而行来制作一个 Range<String.Index>。
所以我必须将 Range 创建更改为这种非常复杂的方式:
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
为什么 Swift 对我来说仅仅创建一个包含 2 个整数和半开范围运算符的范围还不够好? (..<)
与“swift”形成鲜明对比,在javascript中我可以简单地做chars.substr(idx, 1)
【问题讨论】:
-
因为字符没那么简单。它们并不都占用相同数量的内存。请参阅字符串文档中的Counting Characters 部分。