Sobes.tech
Middle+

Como são armazenados os opcionais na memória?

sobes.tech IA

Resposta da IA

Opcional em Swift representa uma enumeração com dois casos: .none (ou nil) e .some(Wrapped).

enum Optional<Wrapped> {
    case none
    case some(Wrapped)
}

Quando o opcional contém um valor (.some(Wrapped)), ele armazena o valor em si do tipo Wrapped além de um bit adicional que indica a presença do valor. Se o opcional for nil (.none), apenas esse bit ou um padrão especial de bytes que indica a ausência de valor é armazenado.

A forma de armazenamento pode variar dependendo do tipo Wrapped e da arquitetura do processador (32-bit vs 64-bit), mas a ideia geral é usar algum indicador de presença de valor. Para tipos de referência, por exemplo, nil pode ser representado por um ponteiro nulo, quando não é necessário um indicador separado ou quando é combinado. Para tipos de valor, é necessário espaço adicional para o indicador.

Exemplo com arquitetura de 64 bits e indicador:

  • Se Optional<T> contém um valor: memória para T + 1 bit (ou byte) para o indicador "há valor".
  • Se Optional<T> é nil: geralmente armazena um padrão especial de bytes ou é combinado com um ponteiro para tipos de referência.

É importante notar que, para tipos cujo tamanho é menor que seu alinhamento natural (por exemplo, Bool em um sistema de 64 bits), o indicador de presença pode estar "embutido" nos bits restantes, economizando memória. Essa otimização é chamada de "Nullable Pointer Optimization" para tipos de referência e é semelhante para alguns tipos de valor.