Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何使用CGPoint的原始类型创建枚举?_Swift - Fatal编程技术网

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:

灵感来源于。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: 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,通过conform
stringliteralcoverable

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"