2014-06-11 33 views
25

this question'den ilham alındı. Herhangi bir ham türü ile enum oluşturmak için hızlı destek, bu yüzden ham CGPoint türü ile enum oluşturmak mümkün olacak.Ham türü CGPoint ile enum nasıl oluşturulur?

Ama bu kod Peki CGPoint ham türü ile enum ilan etmek hata

<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 
    ^

aşağıdaki

enum MyEnum : CGPoint { 
    case Zero 
} 

derlemek değil mi?

cevap

34

Verilen kodda iki hata var.

İlki

error: raw type 'CGPoint' is not convertible from any literal 
    enum MyEnum : CGPoint { 

Buradan problemin uygun tarafından o String konvertibl edebi yapmak CGPoint uzatmaktır çözmek için literal

Bir biçiminden CGPoint konvertibl yapmak gerekir ise StringLiteralConvertible

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 
    } 
} 

Artık dize değişmezinden CGPoint oluşturabiliriz!

var p : CGPoint = "2,3" 
println(p) // print (2.0,3.0) 

ikinci hata, şimdi düzeltmek sadece kendisine edebi

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) 

birkaç ip atamak ve şimdi CGPoint ham türü ile enum sahip kolaydır

error: enum cases require explicit raw values when the raw type is not integer literal convertible 
     case Zero 
     ^

olduğunu


kullanımı mümkün değildir gibi

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" 

başlığın gelen CGPoint oluşturmak için daha güzel olacak, ancak, görünüyor. grammar

literal → integer-literal­ floating-point-literal­ string-literal­ 

itibaren

orada hazır bilgi sadece üç türü vardır, bu yüzden

+2

durumda Zero = 'gibi başlığın gelen oluşturmak için daha güzel olacaktır (0,0)' ama anlamaya nasıl olamaz henüz yap. –

+0

Otomatik olarak 'switch' ile çalışacak mı yoksa desen eşleştirme operatörünü geçersiz kılmaya mı çalışacaksınız? – Sulthan

+0

@Sulthan Güncellememi görün –

3

(eğer (1, 2) olmak 1.2 istemiyorsanız) dize literal burada tek seçenek Gerçekten Bryan Chen'in çözümü gibi ama bir alternatifle geldim.Şimdi

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) 
    } 
} 

bunu hepimiz "ham" işlemleri yapabilirsiniz:

var p = CGPoint.fromRaw((10, 20)) //from tuple 

Biz de bir switch kullanabilirsiniz: Gerçekten Çeteleler kullanır vermez Ancak

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") 
} 

, seni default kasasına ihtiyacınız var ve kısa .Zero isimlerini kullanamazsınız.

9

Aslında doğru bir yol olabilir. Bu şekilde CGPoint sahip olmanızı sağlar koddur bir RawValueenum ait:

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" 
İlgili konular