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


С документация Apple:

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

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

12 228

12 ответов:

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

var name: String? = "Bertie"

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

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

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

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

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

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

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

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

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


как создать optionals

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

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")
}

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


только optionals может быть 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.

проверка и использование дополнительного

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

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

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

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)")

для чего существуют опционы?

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

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

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

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

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


по сравнению с nil

раньше вы могли использовать любой дополнительный как Boolean:

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

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

var ambiguous: Boolean? = false

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

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


Свифт трюки

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

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

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

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

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


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

используя ? для создания необязательного является синтаксический сахар, включенный компилятором 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

позволяя optionals равняться nil включен протоколом ExpressibleByNilLiteral (прежнее название NilLiteralConvertible). Опция создается с помощью Optional второй инициализатор,public init(nilLiteral: ()). Документы говорят, что вы не должны использовать ExpressibleByNilLiteral для всего, кроме optionals, так как это изменило бы значение 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

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

// 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's a match!") // Prints "It's a match!"
}

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

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

if nil == name { ... }

Именование Optionals

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


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

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

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

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


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

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

Антигониш


больше ресурсов:

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

var error: NSError? = nil

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

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

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

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

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

    var aString = nil //error

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

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

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

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

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

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

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

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

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

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

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

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

var hw = "Hello World"

здесь, даже если 'hw' является строкой, он не может быть использован в операторе if, как в objective C.

//This is an error

if hw

 {..}

для этого его нужно создать как,

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}

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

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

Отрывок Из: Apple Inc. "Язык Программирования Swift."iBooks. https://itun.es/gb/jEUH0.l

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

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

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

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

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

enter image description here

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

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

2) Неявно Развернул Необязательно

 if let unwrappedAge = age {

 // continue in here

 }

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

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

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

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

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

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

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

когда я начал изучать 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?

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

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

спасибо...Счастливого Кодирования

от https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html:

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

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

хорошо...

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

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

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

в частности, в результате необязательный вызов цепочки имеет тот же тип, что и ожидаемое возвращаемое значение, но завернутый в необязательный. Свойство, которое обычно возвращает 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's not optional and show a compile time error

вот основной учебник в деталях, от Apple Developer Committee:Дополнительные Цепочки

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

var middleName: String?

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

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

var middleName: String? = nil

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

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