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?
risposta
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)
}
Inoltre, esiste un altro tipo chiamato "ImplicitlyUnwrappedOptional". – Sulthan
e quindi credo che la domanda sarebbe ... come vengono implementate le enumerazioni? :) – newacct
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
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
}
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")
}
}
}
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;
}
Bonus: chi knowns la risposta: come e dove possiamo trovare una tale risposta per un determinato seme Swift (solo in caso di modifiche future) –
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