代码之家  ›  专栏  ›  技术社区  ›  inorganik

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

  •  2
  • inorganik  · 技术社区  · 9 年前

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

    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>')
    

    我很困惑为什么我不能简单地提供一个 Range Range<String.Index> .

    范围 以这种过于复杂的方式进行创作:

    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)

    2 回复  |  直到 9 年前
        1
  •  2
  •   vacawama    9 年前

    我建议将您的 String [Character] 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
    }
    
        2
  •  1
  •   Paulo Mattos    9 年前

    Swift非常小心地提供完全符合Unicode的、类型安全的、, String

    索引给定 Character 性格 是一个或多个Unicode的序列 它(当组合在一起时)产生一个人类可读的字符。特别是,在一个简单的 Int 基于索引的方案可能会导致程序员错误的性能心理模型。

    话虽如此,您始终可以将字符串转换为 Array<Character> 一次轻松(快速!)索引。例如:

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