2016-11-30 18 views
9

Böyle künyelenen değerler için enum (bu bir oyuncak Şeması tercüman projesinden ise) vardır: Value(3) döner çağıran önüne aldığımızdaNeden x olarak Float vakasının Herhangi bir değişkende bir anahtarda eşleşmemesine izin verelim?

init?(value:Any) { 
    switch v { 
    case let v as Int: self = .int(v) 
    case let v as Float: self = .float(v) 
    case let v as Bool: self = .bool(v) 
    ... 
    default: return nil 
    } 
} 

:

enum Value { 
    case int(Int) 
    case float(Float) 
    case bool(Bool) 
    ... 
} 

bunun için bir başlatıcı yazdı beklendiği gibi bir (isteğe bağlı) Value.int (3). Bool's ve diğer tipler de çalışıyor.

Ancak Value(0.1) varsayılan durumu vurur ve nil değerini döndürür.

(doğruluğu ve tavsiye edilen stil için düzenlenmiştir. Bu sorunları işaret için herkese teşekkürler.)

+1

'V' tanımlanır? –

+5

Muhtemelen 'switch value' anlamına gelir. Literal 0.1, "Float" Flo değil – vadian

+0

Luka, benim kötü. Sorunuma aktardığımda kodu biraz değiştiriyordum. "Init? (V: Any) ..." yazmalıdır. – Dietrich

cevap

12

nokta sabitlerini yüzen için varsayılan olayla tip Double değil Float olduğunu. Hızlı standart kitaplık tarafından burada tanımlanmıştır: derleyici tarafından bilinen FloatLiteralType typealias.

+1

Teşekkürler, bu özlü ve aydınlatıcı oldu! – Dietrich

5

type inference dokümantasyonu diyor ki:

Swift hep seçer Double kayan noktalı sayıların türünü çıkarım alması (Float yerine).

Eğer Float kullanmak istiyorsanız, açıkça kullanması gerekiyor literal:

enum Value { 
    case Int(Int) 
    case Float(Float) 
    case Bool(Bool) 
    case Double(Double) 
    init?(v:Any) { 
     switch v { 
     case let v as Int: self = .Int(v) 
     case let v as Float: self = .Float(v) 
     case let v as Bool: self = .Bool(v) 
     case let v as Double: self = .Double(v) 
     default: return nil 
     } 
    } 
} 


Value(v: 0.1) //Infer Double > Result: Double(0.10000000000000001) 
Value(v: Float(0.0002)) //Specify Float > Result: Float(0.000199999995) 
+3

Lütfen kodunuzun neden işe yaradığına dair bir açıklama ekleyin. – milo526

+1

@ milo526 Kod, her şeyin açık olduğunu söylüyor. Anlaması kolay. –

+1

Şimdi anladığım kadarıyla, Float davanız asla eşleşmeyecek, Çift kutunuz bunu yakalayacaktır.Senin kodunun bu noktayı netleştirdiğini sanmıyorum. – Dietrich

1

Btw, sen değişmezleri ile Value türünü init edebilmek istiyorum gibi görünüyor, bu nedenle uygun deneyebilirsiniz türünüzü ExpressibleBy* protokollerine.

gibi:

extension Value: ExpressibleByIntegerLiteral { 
    init(integerLiteral value: Int) { 
     self = .int(value) 
    } 
} 

let v1: Value = 42 // v1 == Value.int(42) 

extension Value: ExpressibleByBooleanLiteral { 
    init(booleanLiteral value: Bool) { 
     self = .bool(value) 
    } 
} 

let v2: Value = true // v2 == Value.bool(true) 

extension Value: ExpressibleByFloatLiteral { 
    init(floatLiteral value: Float) { 
     self = .float(value) 
    } 
} 

let v3: Value = 0.5 // v3 == Value.float(0.5) 
+0

Serin öneri. Bunu gördüm ve yanlış bir şekilde, birçok "ExpressibleBy_Literal" protokolüne aynı anda uymadığımı varsaydım. Ben deneyeceğim, teşekkürler! – Dietrich

+0

Aslında, yaptığımdan çok daha fazlasını seviyorum. Keşke cevabınızı "orijinal soruma yol açan problemle karşılaştığımda zaten yolumun daha güzel bir alternatifi sunmak" için alt kontrol edebilirdim. – Dietrich

İlgili konular