Что такое необязательное значение в Swift?

Из документации Apple:

Вы можете использовать if и let вместе, чтобы работать со значениями, которые могут отсутствовать. Эти значения представлены как дополнительные. Необязательное значение либо содержит значение, либо содержит nil, чтобы указать, что это значение отсутствует. Запишите знак вопроса (?) после типа значения, чтобы пометить значение как необязательное.

Почему вы хотите использовать необязательное значение?

Ответ 1

Необязательный в Swift - тип, который может содержать значение или значение. Опционы записываются путем добавления ? к любому типу:

var name: String? = "Bertie"

Опционы (вместе с Generics) - одна из самых сложных понятий Swift для понимания. Из-за того, как они написаны и используются, легко получить неправильное представление о том, что они собой представляют. Сравните опцию выше с созданием нормальной строки:

var name: String = "Bertie" // No "?" after String

Из синтаксиса выглядит, что необязательная String очень похожа на обычную String. Не это. Необязательная строка не является строкой с включенной "опциональной" настройкой. Это не особая разновидность String. Строка и необязательная строка являются совершенно разными типами.

Здесь самое главное знать: необязательный тип контейнера. Необязательная строка - это контейнер, который может содержать строку. Необязательный Int - это контейнер, который может содержать Int. Подумайте о необязательной форме своего рода посылки. Прежде чем открыть его (или "развернуть" на языке опций), вы не узнаете, содержит ли оно что-то или ничего.

Вы можете увидеть как реализованы дополнительные опции в стандартной библиотеке Swift, введя "Необязательно" в любой файл Swift и щелкнув по нему. Здесь важная часть определения:

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

Необязательный - это просто enum, который может быть одним из двух случаев: .none или .some. Если оно .some, есть связанное значение, которое в приведенном выше примере будет String "Hello". Необязательный использует Generics, чтобы дать тип связанному значению. Тип необязательной строки не String, она Optional, а точнее Optional<String>.

Все, что Swift делает с опциями, - это волшебство, позволяющее читать и писать код более свободно. К сожалению, это скрывает то, как оно работает. Я позже рассмотрю некоторые из трюков.

Примечание.. Я буду говорить о дополнительных переменных много, но это прекрасно, чтобы создавать необязательные константы. Я отмечаю все переменные своим типом, чтобы упростить понимание типов типов, которые создаются, но вам не нужно в свой собственный код.


Как создать дополнительные опции

Чтобы создать необязательный параметр, добавьте ? после типа, который вы хотите обернуть. Любой тип может быть необязательным, даже ваши собственные пользовательские типы. У вас не может быть пробела между типом и ?.

var name: String? = "Bob" // Create an optional String that contains "Bob"
var peter: Person? = Person() // An optional "Person" (custom type)

// A class with a String and an optional String property
class Car {
var modelName: String // must exist
var internalName: String? // may or may not exist
}

Использование опций

Вы можете сравнить опцию с nil, чтобы узнать, имеет ли она значение:

var name: String? = "Bob"
name = nil // Set name to nil, the absence of a value
if name != nil {
    print("There is a name")
}
if name == nil { // Could also use an "else"
    print("Name has no value")
}

Это немного запутанно. Это подразумевает, что факультативно это то или другое. Это либо ноль, либо это "Боб". Это неверно, опционально не превращается во что-то другое. Сравнение с nil - это трюк для упрощения чтения кода. Если необязательный равен nil, это означает, что в настоящее время перечисление установлено на .none.


Только опции могут быть nil

Если вы попытаетесь установить необязательную переменную в nil, вы получите сообщение об ошибке.

var red: String = "Red"
red = nil // error: nil cannot be assigned to type 'String'

Другой способ взглянуть на опции - это дополнение к обычным переменным Swift. Они являются аналогами переменной, которая, как гарантируется, имеет значение. Свифт - осторожный язык, который ненавидит двусмысленность. Большинство переменных определяются как необязательные, но иногда это невозможно. Например, представьте себе контроллер представления, который загружает изображение из кеша или из сети. Он может иметь или не иметь этого изображения во время создания контроллера представления. Невозможно гарантировать значение переменной изображения. В этом случае вам придется сделать это необязательным. Он начинается с nil, и когда изображение будет восстановлено, необязательный получает значение.

Использование опциона показывает намерение программистов. По сравнению с Objective-C, где любой объект может быть равен нулю, Swift требует, чтобы вам было ясно, когда значение может отсутствовать и когда оно гарантировано.


Чтобы использовать опцию, вы "разворачиваете" ее

Необязательный String не может использоваться вместо фактического String. Чтобы использовать обернутое значение внутри необязательного, вам необходимо развернуть его. Самый простой способ развернуть необязательный - добавить ! после необязательного имени. Это называется "вскрытием силы". Он возвращает значение внутри необязательного (в качестве исходного типа), но если необязательный параметр nil, это приводит к сбою во время выполнения. Перед развертыванием вы должны быть уверены, что есть значение.

var name: String? = "Bob"
let unwrappedName: String = name!
print("Unwrapped name: \(unwrappedName)")

name = nil
let nilName: String = name! // Runtime crash. Unexpected nil.

Проверка и использование опционального

Поскольку вы всегда должны проверять нуль перед распаковкой и использовать опцию, это общий шаблон:

var mealPreference: String? = "Vegetarian"
if mealPreference != nil {
    let unwrappedMealPreference: String = mealPreference!
    print("Meal: \(unwrappedMealPreference)") // or do something useful
}

В этом шаблоне вы проверяете, присутствует ли значение, а затем, когда вы уверены, что это так, вы принудительно разворачиваете его во временную константу. Поскольку это такая обычная вещь, Swift предлагает ярлык, используя "if let". Это называется "необязательным связыванием".

var mealPreference: String? = "Vegetarian"
if let unwrappedMealPreference: String = mealPreference {
    print("Meal: \(unwrappedMealPreference)") 
}

Это создает временную константу (или переменную, если вы замените let на var), область видимости которой находится только в фигурных скобках if. Поскольку использование имени типа "unwrappedMealPreference" или "realMealPreference" является бременем, Swift позволяет повторно использовать имя исходной переменной, создавая временную в пределах области скобок

var mealPreference: String? = "Vegetarian"
if let mealPreference: String = mealPreference {
    print("Meal: \(mealPreference)") // separate from the other mealPreference
}

Здесь приведен код, демонстрирующий, что используется другая переменная:

var mealPreference: String? = "Vegetarian"
if var mealPreference: String = mealPreference {
    print("Meal: \(mealPreference)") // mealPreference is a String, not a String?
    mealPreference = "Beef" // No effect on original
}
// This is the original mealPreference
print("Meal: \(mealPreference)") // Prints "Meal: Optional("Vegetarian")"

Необязательное связывание работает, проверяя, является ли необязательный равным нулю. Если это не так, он разворачивает опцию в предоставленную константу и выполняет блок. В Xcode 8.3 и более поздних версиях (Swift 3.1) попытка распечатать необязательный такой вариант приведет к бесполезному предупреждению. Используйте опцию debugDescription, чтобы отключить ее:

print("\(mealPreference.debugDescription)")

Что такое опции для?

Варианты имеют два варианта использования:

  • Вещи, которые могут потерпеть неудачу (я ожидал чего-то, но ничего не получил)
  • Вещи, которые сейчас ничего, но могут быть чем-то позже (и наоборот)

Некоторые конкретные примеры:

  • Свойство, которое может быть там или не существует, например middleName или spouse в классе Person
  • Метод, который может возвращать значение или ничего, например поиск соответствия в массиве
  • Метод, который может возвращать результат или получать ошибку и ничего не возвращать, например, пытаться прочитать содержимое файла (которое обычно возвращает данные файла), но файл не существует
  • Свойства делегата, которые не всегда должны быть установлены и обычно устанавливаются после инициализации
  • Для свойств weak в классах. То, на что они указывают, может быть установлено в nil в любое время
  • Большой ресурс, который может быть выпущен для восстановления памяти
  • Если вам нужен способ узнать, когда значение было установлено (данные еще не загружены > данные) вместо использования отдельного dataLoaded Boolean

Опционы не существуют в Objective-C, но существует эквивалентная концепция, возвращающая нуль. Методы, которые могут возвращать объект, могут возвращать нуль. Это означает "отсутствие действительного объекта" и часто используется, чтобы сказать, что что-то пошло не так. Он работает только с объектами Objective-C, а не с примитивами или базовыми C-типами (перечислениями, структурами). Objective-C часто имели специализированные типы для представления отсутствия этих значений (NSNotFound, который действительно NSIntegerMax, kCLLocationCoordinate2DInvalid для представления недопустимой координаты, -1 или некоторое отрицательное значение также используются). Кодер должен знать об этих специальных значениях, поэтому они должны быть документированы и изучены для каждого случая. Если метод не может принимать nil в качестве параметра, это должно быть документировано. В Objective-C, nil был указателем, так как все объекты были определены как указатели, но nil указывал на конкретный (нулевой) адрес. В Swift nil является литералом, который означает отсутствие определенного типа.


Сравнение с nil

Раньше вы использовали любую опцию как Boolean:

let leatherTrim: CarExtras? = nil
if leatherTrim {
    price = price + 1000
}

В более поздних версиях Swift вам нужно использовать leatherTrim != nil. Почему это? Проблема в том, что a Boolean можно обернуть в необязательный. Если у вас есть Boolean:

var ambiguous: Boolean? = false

он имеет два типа "ложных": один, где нет значения, и один, где он имеет значение, но значение false. Swift ненавидит двусмысленность, поэтому теперь вы всегда должны проверить опцию nil.

Вы можете задаться вопросом, что точка необязательного Boolean? Как и в случае с другими опциями, состояние .none может указывать на то, что значение пока неизвестно. На другом конце сетевого вызова может быть что-то, что требует времени для опроса. Необязательные булевы также называются трехзначные булевы"


Быстрые трюки

Swift использует некоторые трюки, чтобы позволить опциональным функциям работать. Рассмотрим эти три строки обычного перспективного кода;

var religiousAffiliation: String? = "Rastafarian"
religiousAffiliation = nil
if religiousAffiliation != nil { ... }

Ни одна из этих строк не должна компилироваться.

  • Первая строка устанавливает необязательную строку с использованием строкового литерала, двух разных типов. Даже если это было String, разные типы
  • Вторая строка устанавливает необязательную строку в nil, два разных типа
  • Третья строка сравнивает необязательную строку с nil, двумя разными типами

Я расскажу о некоторых деталях реализации опций, которые позволяют этим линиям работать.


Создание необязательного

Использование ? для создания необязательного синтаксического сахара, включенного компилятором Swift. Если вы хотите сделать это длинным путем, вы можете создать необязательный вариант:

var name: Optional<String> = Optional("Bob")

Это вызывает Optional первый инициализатор public init(_ some: Wrapped), который передает необязательный связанный тип из типа, используемого в круглых скобках.

Еще более длинный способ создания и установки необязательного:

var serialNumber:String? = Optional.none
serialNumber = Optional.some("1234")
print("\(serialNumber.debugDescription)")

Установка опций на nil

Вы можете создать необязательный без начального значения или создать его с начальным значением nil (оба имеют одинаковый результат).

var name: String?
var name: String? = nil

Разрешающие опции равны nil активируются протоколом ExpressibleByNilLiteral (ранее называемым NilLiteralConvertible). Необязательный создается с помощью Optional второго инициализатора public init(nilLiteral: ()). Документы говорят, что вы не должны использовать ExpressibleByNilLiteral для чего угодно, кроме опций, поскольку это изменит значение nil в вашем коде, но это возможно сделать:

class Clint: ExpressibleByNilLiteral {
    var name: String?
    required init(nilLiteral: ()) {
        name = "The Man with No Name"
    }
}

let clint: Clint = nil // Would normally give an error
print("\(clint.name)")

Тот же протокол позволяет вам установить уже созданную опцию nil. Хотя это не рекомендуется, вы можете использовать инициализатор nil literal напрямую:

var name: Optional<String> = Optional(nilLiteral: ())

Сравнение опционального с nil

Опционы определяют два специальных оператора "==" и "! =", которые вы можете увидеть в определении Optional. Первый == позволяет вам проверить, не является ли какой-либо необязательный параметр равным нулю. Два разных варианта, которые установлены на .none, всегда будут равны, если связанные типы совпадают. Когда вы сравниваете с nil, за кулисами Swift создает необязательный один и тот же связанный тип, установленный в .none, то использует это для сравнения.

// How Swift actually compares to nil
var tuxedoRequired: String? = nil
let temp: Optional<String> = Optional.none
if tuxedoRequired == temp { // equivalent to if tuxedoRequired == nil
    print("tuxedoRequired is nil")
}

Второй оператор == позволяет сравнить два дополнительных параметра. Оба должны быть одного типа, и этот тип должен соответствовать Equatable (протокол, который позволяет сравнивать вещи с обычным оператором "==" ). Swift (предположительно) разворачивает два значения и сравнивает их напрямую. Он также обрабатывает случай, когда один или оба варианта являются .none. Обратите внимание на различие между сравнением с литералом nil.

Кроме того, он позволяет сравнить любой тип Equatable с необязательной упаковкой, которая имеет тип:

let numberToFind: Int = 23
let numberFromString: Int? = Int("23") // Optional(23)
if numberToFind == numberFromString {
    print("It a match!") // Prints "It a match!"
}

За кулисами Swift обертывает необязательный параметр как необязательный перед сравнением. Он также работает с литералами (if 23 == numberFromString {)

Я сказал, что есть два оператора ==, но на самом деле есть третья, которая позволяет вам поставить nil в левую часть сравнения

if nil == name { ... }

Варианты именования

Существует нет соглашения Swift для именования необязательных типов по-разному, не относящихся к необязательным типам. Люди избегают добавлять что-то к имени, чтобы показать, что оно необязательно (например, "optionalMiddleName" или "possibleNumberAsString" ), и пусть объявление показывает, что это необязательный тип. Это становится затруднительным, если вы хотите назвать что-то, чтобы удерживать значение от опционального. Имя "middleName" означает, что это тип String, поэтому, когда вы извлекаете из него значение String, вы можете часто заканчивать такими именами, как "actualMiddleName" или "unwrappedMiddleName" или "realMiddleName". Используйте необязательную привязку и повторно используйте имя переменной, чтобы обойти это.


Официальное определение

От "Основы" на языке Swift для программирования:

Swift также вводит необязательные типы, которые обрабатывают отсутствие значения. Опционы говорят, что "есть значение, и оно равно x" или "вообще нет значения". Опционы аналогичны использованию nil с указателями в Objective-C, но они работают для любого типа, а не только для классов. Опционы более безопасны и более выразительны, чем nil-указатели в Objective-C, и являются основой большинства самых быстрых функций Swift.

Опционы - пример того, что Swift - это безопасный тип. Swift помогает вам четко понимать типы значений, с которыми может работать ваш код. Если часть вашего кода ожидает String, тип безопасности предотвращает передачу Int Int по ошибке. Это позволяет вам уловить и исправить ошибки как можно раньше в процессе разработки.


Чтобы закончить, вот стихотворение от 1899 года о вариантах:

Вчера на лестнице Я встретил человека, которого там не было. Сегодня он не был здесь
Я желаю, я желаю, чтобы он ушел

Antigonish


Дополнительные ресурсы:

Ответ 2

Возьмем пример NSError, если нет возвращенной ошибки, вы хотите сделать его необязательным для возврата Nil. Нет смысла назначать ему значение, если нет ошибки.

var error: NSError? = nil

Это также позволяет вам иметь значение по умолчанию. Таким образом, вы можете установить метод по умолчанию, если функция ничего не передается

func doesntEnterNumber(x: Int? = 5) -> Bool {
    if (x == 5){
        return true
    } else {
        return false
    }
}

Ответ 3

У вас нет переменной, указывающей на nil в Swift - нет указателей и нулевых указателей. Но в API вы часто хотите указать либо конкретный вид стоимости, либо недостаток значения - например, у моего окна есть делегат, и если да, то кто это? Опционы - это безопасный для Swift безопасный для использования в памяти способ сделать это.

Ответ 4

Я сделал короткий ответ, который суммирует большую часть вышесказанного, чтобы очистить неопределенность, которая была у меня в голове, как новичок:

Против Objective-C переменная не может содержать nil в Swift, поэтому добавлен необязательный тип переменной (переменные, суффиксные с помощью??):

    var aString = nil //error

Большая разница заключается в том, что необязательные переменные непосредственно не хранят значения (как обычные переменные Obj-C), они содержат два состояния: " имеет значение" или " имеет значение nil":

    var aString: String? = "Hello, World!"
    aString = nil //correct, now it contains the state "has nil"

Это, вы можете проверить эти переменные в разных ситуациях:

if let myString = aString? {
     println(myString)
}
else { 
     println("It nil") // this will print in our case
}

Используя "!" суффикс, вы также можете получить доступ к значениям, заключенным в них, , только если они существуют. (т.е. не nil):

let aString: String? = "Hello, World!"
// var anotherString: String = aString //error
var anotherString: String = aString!

println(anotherString) //it will print "Hello, World!"

Вот почему вам нужно использовать "?" а также "!" и не использовать их по умолчанию. (это было мое самое большое недоумение)

Я также согласен с ответом выше: Необязательный тип не может использоваться как логическое.

Ответ 5

В объектных переменных C без значения были равны "nil" (также можно было использовать значения "nil", такие же, как 0 и false), поэтому можно было использовать переменные в условных операторах (переменные, имеющие значения одинаковые как "TRUE", а те, у которых нет значений, равны "FALSE" ).

Swift обеспечивает безопасность типов, предоставляя "необязательное значение". т.е. он предотвращает формирование ошибок при назначении переменных разных типов.

Итак, в Swift для условных операторов могут быть предоставлены только булевы.

var hw = "Hello World"

Здесь даже, хотя "hw" - это строка, она не может использоваться в операторе if, как в объекте C.

//This is an error

if hw

 {..}

Для этого он должен быть создан как

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}

Ответ 6

Дополнительное значение позволяет вам показать отсутствие значения. Немного как NULL в SQL или NSNull в Objective-C. Я думаю, это будет улучшением, поскольку вы можете использовать его даже для "примитивных" типов.

// Reimplement the Swift standard library optional type
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)"

Отрывок из: Apple Inc. "Быстрый язык программирования". интерактивные книги. https://itun.es/gb/jEUH0.l

Ответ 7

Необязательный означает, что Swift не совсем уверен, соответствует ли значение типу: например, Int? означает, что Swift не совсем уверен, является ли число Int.

Чтобы удалить его, вы можете использовать три метода.

1) Если вы абсолютно уверены в типе, вы можете использовать восклицательный знак, чтобы развернуть его, например:

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

Если вы принудительно распакуете опцию, и она равна нулю, вы можете столкнуться с этой ошибкой при сбое:

введите описание изображения здесь

Это не обязательно безопасно, поэтому здесь метод, который может предотвратить сбой, если вы не уверены в типе и значении:

Методы 2 и три защищают эту проблему.

2) Неявно освобожденный необязательный

 if let unwrappedAge = age {

 // continue in here

 }

Обратите внимание, что развернутый тип теперь Int, а не Int?.

3) Заявление охранника

 guard let unwrappedAge = age else { 
   // continue in here
 }

Отсюда вы можете перейти и использовать развернутую переменную. Убедитесь, что вы принудительно разворачиваете (с помощью!), Если вы уверены в типе переменной.

Удачи вам в вашем проекте!

Ответ 8

Когда я начал изучать Swift, было очень сложно понять, почему необязательный.

Давайте подумаем таким образом. Рассмотрим класс Person, который имеет два свойства name и company.

class Person: NSObject {

    var name : String //Person must have a value so its no marked as optional
    var companyName : String? ///Company is optional as a person can be unemployed that is nil value is possible

    init(name:String,company:String?) {

        self.name = name
        self.companyName = company

    }
}

Теперь создадим несколько объектов Person

var tom:Person = Person.init(name: "Tom", company: "Apple")//posible
var bob:Person = Person.init(name: "Bob", company:nil) // also Possible because company is marked as optional so we can give Nil

Но мы не можем пройти Nil до name

var personWithNoName:Person = Person.init(name: nil, company: nil)

Теперь поговорим о том, почему мы используем optional?. Давайте рассмотрим ситуацию, когда мы хотим добавить Inc после того, как название компании, например apple, будет apple Inc. Нам нужно добавить Inc после названия компании и распечатать.

print(tom.companyName+" Inc") ///Error saying optional is not unwrapped.
print(tom.companyName!+" Inc") ///Error Gone..we have forcefully unwrap it which is wrong approach..Will look in Next line
print(bob.companyName!+" Inc") ///Crash!!!because bob has no company and nil can be unwrapped.

Теперь давайте изучим, почему факультативно применяется.

if let companyString:String = bob.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.

    print(companyString+" Inc") //Will never executed and no crash!!!
}

Позволяет заменить bob на tom

if let companyString:String = tom.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.

    print(companyString+" Inc") //Will never executed and no crash!!!
}

И Поздравление! мы имеем дело с optional?

Итак, точки реализации

  • Мы будем отмечать переменную как необязательную, если ее возможно быть Nil
  • Если мы хотим использовать эту переменную где-то в компиляторе кода, напомню, что нам нужно проверить, правильно ли мы имеем дело с этой переменной если он содержит Nil.

Спасибо... Счастливое кодирование

Ответ 9

Из https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html:

Необязательное сцепление - это процесс запроса и вызова свойств, методов и подписок для необязательного элемента, который в настоящее время может быть равен нулю. Если необязательный параметр содержит значение, вызов свойства, метода или индекса не выполняется; если необязательный параметр равен nil, вызов свойства, метода или нижнего индекса возвращает nil. Несколько запросов могут быть объединены в цепочку, и вся цепочка завершится неудачно, если какое-либо звено в цепочке равно нулю.

Чтобы понять глубже, прочитайте ссылку выше.

Ответ 10

Давайте поэкспериментируем с нижеприведенным кодом Игровая площадка. Надеюсь, что он очистит идею, что является необязательным, и причина ее использования.

var sampleString: String? ///Optional, Possible to be nil

sampleString = nil ////perfactly valid as its optional

sampleString = "some value"  //Will hold the value

if let value = sampleString{ /// the sampleString is placed into value with auto force upwraped.

    print(value+value)  ////Sample String merged into Two
}

sampleString = nil // value is nil and the

if let value = sampleString{

    print(value + value)  ///Will Not execute and safe for nil checking
}

//   print(sampleString! + sampleString!)  //this line Will crash as + operator can not add nil

Ответ 11

Что ж...

? (Необязательно) указывает, что ваша переменная может содержать значение ноль в то время как ! (unwrapper) указывает, что ваша переменная должна иметь память (или значение), когда она используется (пытается получить значение из нее) во время выполнения.

Основное отличие состоит в том, что необязательное связывание завершается неудачно, когда необязательное значение равно nil, тогда как принудительное развертывание вызывает ошибку времени выполнения, если необязательное значение равно nil.

Чтобы отразить тот факт, что необязательное сцепление может быть вызвано для значения nil, результатом необязательного вызова связывания всегда является необязательное значение, даже если запрашиваемое свойство, метод или индекс, возвращают неопциональное значение. Это необязательное возвращаемое значение можно использовать, чтобы проверить, был ли необязательный вызов цепочки успешным (возвращаемая необязательная содержит значение) или не удалась из-за значения nil в цепочке (возвращаемое необязательное значение равно nil).

В частности, результат необязательного вызова цепочки имеет тот же тип, что и ожидаемое возвращаемое значение, но заключен в необязательный. Свойство, которое обычно возвращает Int, будет возвращать Int? при доступе через необязательную цепочку.

var defaultNil : Int?  // declared variable with default nil value
println(defaultNil) >> nil  

var canBeNil : Int? = 4
println(canBeNil) >> optional(4)

canBeNil = nil
println(canBeNil) >> nil

println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper

var canNotBeNil : Int! = 4
print(canNotBeNil) >> 4

var cantBeNil : Int = 4
cantBeNil = nil // can't do this as it not optional and show a compile time error

Вот базовое учебное пособие от Apple Developer Committee: Необязательная цепочка

Ответ 12

Необязательным в Swift является тип, который может содержать либо значение, либо отсутствие значения. Факультативные написаны добавлением ? к любому типу:

var name: String?

Вы можете обратиться к этой ссылке, чтобы получить глубокие знания: https://medium.com/@agoiabeladeyemi/optionals-in-swift-2b141f12f870

Ответ 13

Вот эквивалентное необязательное объявление в Swift:

var middleName: String?

Это объявление создает переменную с именем middleName типа String. Значок вопроса (?) После типа переменной String указывает, что переменная middleName может содержать значение, которое может быть либо строкой, либо нулем. Любой, кто смотрит на этот код, сразу знает, что middleName может быть nil. Это самодокументируемо!

Если вы не укажете начальное значение для необязательной константы или переменной (как показано выше), то для вас автоматически устанавливается значение nil. Если вы предпочитаете, вы можете явно установить начальное значение на nil:

var middleName: String? = nil

для более подробной информации для дополнительного чтения ниже ссылки

http://www.iphonelife.com/blog/31369/swift-101-working-swifts-new-optional-values