我正在尝试扩展Character以符合Strideable,以便创建一个Character类型的CountableClosedRange。最后,我希望有这样的东西,打印整个字母表:
("A"..."Z").forEach{
print($0)
}目前,我正在使用UnicodeScalar类型来计算两个字符之间的距离。由于标量在Character类型中不可用,我需要从该字符创建一个字符串,获取第一个标量的值,并计算它们之间的距离:
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附带的类型。
public protocol Strideable : Comparable {
/// A type that can represent the distance between two values of `Self`.
associatedtype Stride : SignedNumber
// ...
}我遗漏了什么?
发布于 2016-10-12 10:44:36
如前所述,由于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>,如果需要的话,可以自由地将每个单独的元素转换为Character或String:
("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)}发布于 2016-10-11 18:07:42
即使你能让它发挥作用,它也不会像你期望的那样起作用。你认为"A“和"Z”之间有多少个字符?如果不定义编码,这就没有意义。事实上,如果你探究字符是如何符合可比的,它们的表现更像浮点数,而不是整数。例如:
"N" < "Ń" // true
"Ń" < "Ñ" // true
"Ń" < "O" // trueN和O之间有许多对N的修改,这可能是一个无界的数字,因为Unicode具有组合字符的能力。(如果您在Character()中包装这些文件,情况也是一样的。)
https://stackoverflow.com/questions/39982335
复制相似问题