2014-07-03 18 views
11

Zastanawiam się, w jaki sposób typy wartości w Swift (Int, Float ...) są zaimplementowane, aby obsługiwać opcjonalne powiązanie ("?"). Zakładam, że te typy wartości nie są przydzielane na stercie, ale na stosie. Czy więc polegają one na wskaźniku do stosu, który może mieć wartość zerową, czy też bazowa struktura zawiera flagę logiczną?W jaki sposób zaimplementowane są opcjonalne wartości w Swift?

+0

Bonus: kto wiadome odpowiedź: Jak i gdzie możemy znaleźć taką odpowiedź dla danego materiału siewnego Swift (tylko w przypadku zmiany w przyszłości) –

+0

możliwy duplikat [Co oznacza wykrzyknik w języku Swift?] (http://stackoverflow.com/questions/24018327/what-does-an-exclamation-mark- mean-in-the-swift-language) – Sulthan

Odpowiedz

11

Opcje są implementowane jako Swift w postaci enum.

Zobacz Apple's Swift Tour na przykład jak to zrobić:

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

Istnieje również inny typ o nazwie "ImplicitlyUnwrappedOptional". – Sulthan

+6

i wtedy myślę, że pytanie będzie ... w jaki sposób są implementowane enum? :) – newacct

+0

Wyobrażam sobie, że * oznaczone związki * są używane, co oznacza, że ​​każda wartość ma powiązany z nią znacznik. Jak inaczej można przechowywać "Double?"? – wcochran

3

opcjonalne są realizowane, jak pokazano poniżej. Aby to znaleźć, kliknij CMD na deklarację, taką jak var x: Optional<Int>. var x: Int? to po prostu cukier syntaktyczny.

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 jest open source since wczoraj. Można zobaczyć realizację na 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

Większość odpowiedzi po prostu powiedzieć, że OPCJE Swift są realizowane z enum s który nasuwa pytania, w jaki sposób są następnie enum s realizowane. Należy użyć czegoś podobnego do oznaczonych związków C. Na przykład, Swift enum

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

może być mimick'ed w C następująco:

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; 
} 
Powiązane problemy