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

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

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

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

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

 var name: String? = "Bertie" 

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

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

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

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

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

 enum Optional { case none case some(Wrapped) } 

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

Все, что 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, вы получите сообщение об ошибке.

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

Другой способ взглянуть на опции – это дополнение к обычным переменным Swift. Они являются аналогами переменной, которая, как гарантируется, имеет значение. Свифт – осторожный язык, который ненавидит двусмысленность. Большинство переменных определяются как необязательные, но иногда это невозможно. Например, представьте себе controller представления, который загружает изображение из кеша или из сети. Он может иметь или не иметь этого изображения во время создания controllerа представления. Невозможно гарантировать значение переменной изображения. В этом случае вам придется сделать это необязательным. Он начинается с 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)") 

Для чего нужны варианты?

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

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

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

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

Опций не существует в Objective-C, но существует эквивалентная концепция, возвращающая нуль. Методы, которые могут возвращать объект, могут возвращать нуль. Это означает «отсутствие действительного объекта» и часто используется, чтобы сказать, что что-то пошло не так. Он работает только с объектами Objective-C, а не с примитивами или базовыми C-типами (enumsми, структурами). 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 . Почему это? Проблема в том, что Boolean может быть обернуто в необязательный. Если у вас есть Boolean :

 var ambiguous: Boolean? = false 

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

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


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

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

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

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

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

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


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

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

 var name: Optional = Optional("Bob") 

Это вызывает первый инициализатор опциона, 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 ). Необязательный создается с помощью второго инициализатора public init(nilLiteral: ()) , 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 = Optional(nilLiteral: ()) 

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

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

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

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

Кроме того, он позволяет сравнить любой тип Equatable с необязательной 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 { ... } 

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

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


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

Из «Основы» на языке Swift Programming :

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

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


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

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


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

  • Руководство по быстрому программированию
  • Опции в Swift (Medium)
  • WWDC Session 402 «Введение в Swift» (начинается около 14:15)
  • Дополнительные дополнительные советы и рекомендации

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

 var error: NSError? = nil 

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

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

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

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

Против 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'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!" 

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

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

В объективных переменных 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 {..} 

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

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

Выдержка из: Apple Inc. «Язык быстрого программирования». 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! 

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

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

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

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

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 было очень сложно понять, почему это необязательно .

Давайте подумаем так. Давайте рассмотрим class 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 :

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

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

Что ж…

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

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

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

Ниже приведено основное учебное пособие, разработанное Apple Developer Committee: необязательное соединение

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

 var middleName: String? 

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

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

 var middleName: String? = nil 

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

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

Давайте будем гением компьютера.