Ошибка при распаковке

Я создал новый оператор, который привязывает значение к цели, только если значение не равно нулю, в противном случае ничего не делает. В основном это синтетический сахар, if let foo = foo { faa = foo } :

 infix operator =? {} func =?<T>(inout lhs: T, rhs: T?) { if let rhs = rhs { lhs = rhs } } func =?<T>(inout lhs: T?, rhs: T?) { if let rhs = rhs { lhs = rhs } } 

Таким образом, я могу сохранить некоторые типизации:

 // instead this: if let x = maybeX { z = x } // I can do this: z =? x 

Моя проблема в том, что когда я добираюсь до строки выполнения ( z =? x ), я сбой даже перед входом в реализацию func с исключением:

 fatal error: unexpectedly found nil while unwrapping an Optional value 

Кажется, Swift пытается заставить распаковать x даже когда реализация принимает T? ,

Есть идеи?

Это оказалось моей ошибкой … Я использовал foo.z = ... где foo был nil UIImageView! … дамм просмотров от nib …

Я бы с радостью изменил свою реализацию с помощью оператора nil coalescing после предложения @RMenke, но насколько я знаю, это приведет к избыточному действию установки z в z, когда x равно nil … например:

 var z = someFoo() var x: Int? = nil z = x ?? z // will this re-write z's reference to z again or simply do nothing? 

@MartinR сделал важный комментарий:

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

Пытаясь решить проблему, я сделал следующее расширение как более чистую версию подхода _ = foo.map... :

 extension Optional { public func use<U>(@noescape f: (Wrapped) throws -> U) rethrows { _ = try self.map(f) } } //then: x.use{ z = $0 } 

Вероятно, это лучше, так как он не вызывает z setter, когда x равен нулю, но является ли это самым чистым / ясным способом?

Ваш оператор работает, но вы должны были использовать целые опции: foo? .z = …

Однако это даст вам еще один вид ошибки, когда foo – это nil, который вы можете исправить, добавив

 func =?<T>(lhs: T??, rhs: T?) -> () {} 

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

  • Сократите время от NSDate SWIFT
  • LAContext изменить название кнопки UIAlertController
  • Совместное использование данных Realm с WatchOS
  • Утечка памяти при изменении размера UIImage
  • Что это означает в Свифте?
  • Загрузка контактов с iPhone в Swift
  • Набор и протоколы в Swift
  • Пользовательский интерфейс не обновляется при вызове основного потока Swift
  • Как программно установить вид спереди / сзади?
  • Высота UIScrollView при добавлении контента программно в UIStackView
  • Можно ли использовать класс Objective-C в моей библиотеке Swift framework?
  • Interesting Posts

    UIViewController обрабатывает ориентацию iOS 6.0 на iPad

    Firebase, как проверить успешность транзакции или потерпеть неудачу?

    Как создать фреймворк или библиотеку для других разработчиков, безопасный способ?

    iOS: уведомление о загрузке MKMapView и добавление аннотаций / наложений?

    Медленное расширение рассылки iOS

    iOS idleTimerDisabled поведение

    Можно ли использовать байтовые смещения, чтобы найти соответствующую строку в исходном коде для моей трассировки стека ios?

    Где я могу найти хороший учебник по синхронизации IOS Calender?

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

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

    Загрузка изображений с веб-сервера для отображения сетчатки iOS

    Кнопка обратной связи навигационного контроллера

    Как установить высоту ярлыка для автоматической настройки в Read More / Less with Swift 3?

    UICollectionView автоматически сортирует ячейки UICollectionViewFlowLayout

    Очень простое распознавание изображений на iOS

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