我正在尝试扩展 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>
, 并且可以自由地将每个单独的元素转换为 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)}
关于swift - 创建一个 CountableClosedRange<Character>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39982335/