Swift 如何使用CGPoint的原始类型创建枚举?
灵感来源于。Swift支持使用任何原始类型创建枚举,因此能够使用CGPoint的原始类型创建枚举会很好 但这段代码无法编译Swift 如何使用CGPoint的原始类型创建枚举?,swift,Swift,灵感来源于。Swift支持使用任何原始类型创建枚举,因此能够使用CGPoint的原始类型创建枚举会很好 但这段代码无法编译 enum MyEnum : CGPoint { case Zero } 有以下错误 <REPL>:50:15: error: raw type 'CGPoint' is not convertible from any literal enum MyEnum : CGPoint { ^ <REPL>:51:10:
enum MyEnum : CGPoint {
case Zero
}
有以下错误
<REPL>:50:15: error: raw type 'CGPoint' is not convertible from any literal
enum MyEnum : CGPoint {
^
<REPL>:51:10: error: enum cases require explicit raw values when the raw type is not integer literal convertible
case Zero
^
:50:15:错误:原始类型“CGPoint”不能从任何文本转换
枚举MyEnum:CGPoint{
^
:51:10:错误:当原始类型不是整型文字可转换时,枚举案例需要显式原始值
案例零
^
那么如何用CGPoint的原始类型声明enum呢?给定代码中有两个错误 第一个是
error: raw type 'CGPoint' is not convertible from any literal
enum MyEnum : CGPoint {
所以我们需要使CGPoint可以从literal转换
解决这个问题的一种方法是扩展CGPoint,通过conformstringliteralcoverable
extension CGPoint : StringLiteralConvertible {
static func convertFromStringLiteral(value: String) -> CGPoint {
return NSPointFromString(value) // CGPointFromString on iOS
}
static func convertFromExtendedGraphemeClusterLiteral(value: String) -> CGPoint {
return NSPointFromString(value) // CGPointFromString on iOS
}
}
我们现在可以从字符串文字创建CGPoint了
var p : CGPoint = "2,3"
println(p) // print (2.0,3.0)
第二个错误是
error: enum cases require explicit raw values when the raw type is not integer literal convertible
case Zero
^
现在很容易修复,只需给它分配一些字符串文字
enum MyEnum : CGPoint {
case Zero = "0, 0"
case One = "1, 1"
case MagicPoint = "0, 42"
}
println(MyEnum.Zero.toRaw()) // (0.0,0.0)
println(MyEnum.One.toRaw()) // (1.0,1.0)
println(MyEnum.MagicPoint.toRaw()) // (0.0,42.0)
现在有了CGPoint原始类型的enum
使用它
if let p = MyEnum.fromRaw(CGPoint(x:0, y:42)) {
switch (p) {
case .Zero:
println("p is (0, 0)")
break
case .One:
println("p is (1, 1)")
break
case .MagicPoint:
println("p is magic point")
break
}
}
// print "p is magic point"
从元组创建CGPoint会更好,但是,看起来这是不可能的 从
文本只有三种类型,因此字符串文本是这里唯一的选项(除非您希望
1.2
成为(1,2)
)我非常喜欢Bryan Chen的解决方案,但我有一个选择。它实际上不使用枚举:
extension CGPoint : RawRepresentable, Equatable {
typealias RawType = (CGFloat, CGFloat)
static let Zero = CGPointZero
static let One = CGPoint(x: 1.0, y: 1.0)
static let MagicPoint = CGPoint(x: 42.0, y: 0.0)
static func fromRaw(raw: RawType) -> CGPoint? {
return CGPoint(x: raw.0, y: raw.1)
}
func toRaw() -> RawType {
return (x, y)
}
}
现在我们可以进行所有“原始”操作:
var p = CGPoint.fromRaw((10, 20)) //from tuple
我们还可以使用开关
:
switch (p) {
case CGPoint.Zero:
println("p is (0, 0)")
case CGPoint.One:
println("p is (1, 1)")
case CGPoint.MagicPoint:
println("p is (42, 0)")
case CGPoint(x: 0, y: 10):
println("p is (0, 10)")
default:
println("Something else")
}
但是,您需要
默认值
大小写,并且不能使用短的.Zero
名称。您实际上可以有一个正确的方法。这是允许您将CGPoint
作为枚举的RawValue
的代码:
enum MyPointEnum {
case zero
}
extension MyPointEnum: RawRepresentable {
typealias RawValue = CGPoint
init?(rawValue: CGPoint) {
if rawValue == CGPoint.zero {
self = .zero
} else {
return nil
}
}
var rawValue: CGPoint {
switch self {
case .zero:
return CGPoint.zero
}
}
}
print(MyPointEnum.zero.rawValue) //prints "(0.0, 0.0)\n"
从元组创建更好,比如case Zero=(0,0)
,但我还不知道如何做。它也会自动与开关一起工作,还是必须覆盖模式匹配运算符?我认为这不再在Swift 2.x上编译+
enum MyPointEnum {
case zero
}
extension MyPointEnum: RawRepresentable {
typealias RawValue = CGPoint
init?(rawValue: CGPoint) {
if rawValue == CGPoint.zero {
self = .zero
} else {
return nil
}
}
var rawValue: CGPoint {
switch self {
case .zero:
return CGPoint.zero
}
}
}
print(MyPointEnum.zero.rawValue) //prints "(0.0, 0.0)\n"