swift - 创建一个 CountableClosedRange<Character>

标签 swift

我正在尝试扩展 Character 以符合 Strideable 以创建 Character 类型的 CountableClosedRange .最后,我想要打印整个字母表的类似这样的东西:

("A"..."Z").forEach{
    print($0)
}

目前,我使用UnicodeScalar 类型来计算两个字符之间的距离。因为 Character 类型不提供标量,所以我需要从 Character 创建一个 String,获取第一个标量的值,并计算它们之间的距离:

extension Character: Strideable {

    func distance(to other: Character) -> Character.Stride {
        return abs(String(self).unicodeScalars.first?.value - String(other).unicodeScalars.first!.value)
    }

    func advanced(by n: Character.Stride) -> Character {
        return Character(UnicodeScalar(String(self).unicodeScalars.first!.value + n))
    }

}

即便如此,我仍然收到错误消息,即 Character 不符合协议(protocol) Strideable_Strideable。编译器似乎没有选择 Strideable 附带的 Stride 关联类型:

public protocol Strideable : Comparable {

    /// A type that can represent the distance between two values of `Self`.
    associatedtype Stride : SignedNumber

    // ...

}

我错过了什么?

最佳答案

如前所述,因为 Character可以由多个 unicode 标量组成,您无法准确确定两个任意字符之间有多少不同的有效字符表示,因此不是符合 Stridable 的良好候选者.

解决您只想打印出字母表的问题的一种方法是符合 UnicodeScalar , 而不是 Character , 至 Stridable – 允许您使用由单个 unicode 代码点表示的字符,并根据该代码点推进它们。

extension UnicodeScalar : Strideable {

    public func distance(to other: UnicodeScalar) -> Int {
        return Int(other.value) - Int(self.value)
    }

    /// Returns a UnicodeScalar where the value is advanced by n.
    ///
    /// - precondition: self.value + n represents a valid unicode scalar.
    ///
    public func advanced(by n: Int) -> UnicodeScalar {
        let advancedValue = n + Int(self.value)
        guard let advancedScalar = UnicodeScalar(advancedValue) else {
            fatalError("\(String(advancedValue, radix: 16)) does not represent a valid unicode scalar value.")
        }
        return advancedScalar
    }
}

现在你可以组成一个CountableClosedRange<UnicodeScalar> , 并且可以自由地将每个单独的元素转换为 CharacterString如果需要:

("A"..."Z").forEach {

    // You can freely convert scalar to a Character or String
    print($0, Character($0), String($0))
}

// Convert CountableClosedRange<UnicodeScalar> to [Character]
let alphabetCharacters = ("A"..."Z").map {Character($0)}

关于swift - 创建一个 CountableClosedRange<Character>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39982335/

相关文章:

swift - Mapbox - calloutAccessoryControllerTapped

ios - 如果通过 segue 从另一个选项卡进入,如何从 Controller 中删除 TabBar?

objective-c - 如何将 Swift 代码导入到 Objective-C?

ios - 删除弹出 View Controller -swift

ios - 在 UIView 上绘制自定义圆角矩形 UIBezierPath

ios - 如何使用 Swift 将自定义字体添加到 iOS 中的 imglyKit SDK 中?

swift - 当我的 ViewController 嵌入到 UINavigationController 中时,如何对值进行排序?

swift - 使用 GameplayKit 在 Tilemap 上寻路

ios - 为什么在页面 View Controller 中使用 KVO 进行观察时应用程序崩溃?以及如何使 KVO 生效?

UITextView AppStore 拒绝中的 HTML 字符串