2014-07-03 4 views
11

Mi chiedo come vengono implementati i tipi di valore in Swift (Int, Float ...) per supportare l'associazione facoltativa ("?"). Suppongo che quei tipi di valore non siano allocati nell'heap, ma nello stack. Quindi, fanno affidamento su qualche tipo di puntatore allo stack che può essere nullo, oppure la struttura sottostante contiene un flag booleano?Come vengono implementati i valori opzionali in Swift?

+0

Bonus: chi knowns la risposta: come e dove possiamo trovare una tale risposta per un determinato seme Swift (solo in caso di modifiche future) –

+0

possibile duplicato di [Cosa significa un punto esclamativo nella lingua Swift?] (http://stackoverflow.com/questions/24018327/what-does-an-exclamation-mark- mean-in-the-swift-language) – Sulthan

risposta

11

Gli optionals sono implementati come tipo enum in Swift.

Vedi Apple's Swift Tour per un esempio di come questo viene fatto:

enum OptionalValue<T> { 
    case None 
    case Some(T) 
} 
+0

Inoltre, esiste un altro tipo chiamato "ImplicitlyUnwrappedOptional". – Sulthan

+6

e quindi credo che la domanda sarebbe ... come vengono implementate le enumerazioni? :) – newacct

+0

Immagino che vengano utilizzate le unioni * taggate, il che significa che ogni valore ha un tag correlato memorizzato con esso. In quale altro modo è possibile memorizzare un 'Double?'? – wcochran

3

Opzionali sono implementate come illustrato di seguito. Per trovare questo, clicca CMD su una dichiarazione come var x: Optional<Int>. var x: Int? è solo zucchero sintattico per quello.

enum Optional<T> : LogicValue, Reflectable { 
    case None 
    case Some(T) 
    init() 
    init(_ some: T) 

    /// Allow use in a Boolean context. 
    func getLogicValue() -> Bool 

    /// Haskell's fmap, which was mis-named 
    func map<U>(f: (T) -> U) -> U? 
    func getMirror() -> Mirror 
} 
9

Swift è open source da ieri. Si può vedere l'implementazione su GitHub: https://github.com/apple/swift/blob/master/stdlib/public/core/Optional.swift

public enum Optional<Wrapped> : ExpressibleByNilLiteral { 

    case none 
    case some(Wrapped) 

    public init(_ some: Wrapped) { self = .some(some) } 

    public init(nilLiteral:()) { 
     self = .none 
    } 

    public var unsafelyUnwrapped: Wrapped { 
     get { 
      if let x = self { 
       return x 
      } 
      _debugPreconditionFailure("unsafelyUnwrapped of nil optional") 
     } 
    } 
} 
2

maggior parte delle risposte è sufficiente dire che optionals Swift sono implementati con enum s che pone la questione di come è allora vengono enum s attuate. È necessario utilizzare qualcosa di simile alle unioni etichettate in C. Ad esempio, l'enum Swift

enum Foo { 
    case None 
    case Name(String) 
    case Price(Double) 
} 

potrebbe essere mimick'ed in C come segue:

enum {FOO_NONE_, FOO_NAME_, FOO_PRICE_}; 
typedef struct { 
    int flavor; // FOO_NONE_, FOO_NAME_ or FOO_PRICE_ 
    union { 
     char *Name; // payload for FOO_STRING_ 
     double Price; // payload for FOO_DOUBLE_ 
    } u; 
}