Как в Swift используются дополнительные значения?

Интересно, как реализованы типы значений в Swift (Int, Float...) для поддержки необязательной привязки ( "?" ). Я предполагаю, что эти типы значений не выделяются в куче, а в стеке. Итак, они полагаются на какой-то указатель на стек, который может быть нулевым, или же базовая структура содержит логический флаг?

Ответ 1

Опционы реализованы как тип enum в Swift.

См. Apple Swift Tour для примера того, как это делается:

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

Ответ 2

Swift является открытым исходным кодом со вчерашнего дня. Вы можете увидеть реализацию на 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")
        }
    }
}

Ответ 3

Варианты реализованы, как показано ниже. Чтобы найти это, нажмите CMD на объявление типа var x: Optional<Int>. var x: Int? - это просто синтаксический сахар для этого.

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

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

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

Ответ 4

Большинство ответов просто говорят, что опции Swift реализованы с помощью enum, который задает вопросы о том, как реализовано enum. Необходимо использовать нечто похожее на меченые союзы в С. Например, Swift enum

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

может быть скопирован на C следующим образом:

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