首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >创建CountableClosedRange<Character>

创建CountableClosedRange<Character>
EN

Stack Overflow用户
提问于 2016-10-11 16:39:21
回答 2查看 504关注 0票数 4

我正在尝试扩展Character以符合Strideable,以便创建一个Character类型的CountableClosedRange。最后,我希望有这样的东西,打印整个字母表:

代码语言:javascript
运行
复制
("A"..."Z").forEach{
    print($0)
}

目前,我正在使用UnicodeScalar类型来计算两个字符之间的距离。由于标量在Character类型中不可用,我需要从该字符创建一个字符串,获取第一个标量的值,并计算它们之间的距离:

代码语言:javascript
运行
复制
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不符合协议Strideable_Strideable的错误。编译器似乎没有选择与Stride相关的类型,这是Strideable附带的类型。

代码语言:javascript
运行
复制
public protocol Strideable : Comparable {

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

    // ...

}

我遗漏了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-12 10:44:36

如前所述,由于Character可以由多个unicode标量组成,因此您无法准确地确定两个任意字符之间存在多少不同的有效字符表示,因此不能很好地满足Stridable的要求。

解决简单打印字母表问题的一种方法是使UnicodeScalar (而不是Character )与Stridable保持一致--允许您处理由单个unicode代码点表示的字符,并根据该代码点对它们进行升级。

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
("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)}
票数 6
EN

Stack Overflow用户

发布于 2016-10-11 18:07:42

即使你能让它发挥作用,它也不会像你期望的那样起作用。你认为"A“和"Z”之间有多少个字符?如果不定义编码,这就没有意义。事实上,如果你探究字符是如何符合可比的,它们的表现更像浮点数,而不是整数。例如:

代码语言:javascript
运行
复制
"N" < "Ń" // true
"Ń" < "Ñ" // true
"Ń" < "O" // true

N和O之间有许多对N的修改,这可能是一个无界的数字,因为Unicode具有组合字符的能力。(如果您在Character()中包装这些文件,情况也是一样的。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39982335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档