Имеет ли Swift оператор нулевой коалесценции, а если нет, то какой пример пользовательского оператора?
Общей особенностью на многих языках, Null Coalescing Operator, является двоичный оператор, часто используемый для сокращения выражений типа:
x = possiblyNullValue NCO valueIfNull
... где NCO
является заполнителем для оператора нулевой коалесценции языков.
Objective C Null Coalescing Operator ?:
, поэтому выражение будет:
x = possiblyNullValue ?: valueIfNull
Вышеприведенное выражение также эквивалентно использованию третичного оператора:
x = someTestForNotNull( possiblyNullValue ) ? possiblyNullValue : valueIfNull
Преимущества оператора Null Coalescing
- Более читаемый код (особенно с длинными именами описательных переменных)
- Уменьшенная возможность типографских ошибок (проверенный var вводится только один раз)
- Нет двойной оценки тестируемой переменной, где тестируемая переменная является получателем, поскольку ее доступ один раз (или необходимость кэшировать ее, чтобы умышленно избегать двойной оценки).
Ответы
Ответ 1
С Swift 2.2 (Xcode 6, beta 5) it ??
var x: Int?
var y: Int? = 8
var z: Int = x ?? 9000
// z == 9000
z = y ?? 9001
// z == 8
a ?? b
эквивалентен следующему коду:
a != nil ? a! : b
И с Beta 6 вы можете сделать это:
x ?? y ?? 1 == 8
Ответ 2
(Также см. сообщение в блоге)
Нет, Swift в настоящее время не поддерживает нулевой оператор коалесценции.
Определение пользовательского оператора Null Coales для Swift
Пользовательский оператор может быть определен для Swift со следующими соображениями относительно языка Swift:
Swift и Nil
Swift поддерживает нулевую концепцию через свой Необязательный тип (Дискриминационный Союз сортов), который либо содержит значение базового типа, либо не имеет значения (указано nil) и должен быть явно определен как необязательный:
var a : String?
Необязательный тип никогда не может быть nil или назначен nil. Поэтому можно ожидать, что пользовательский двоичный NCO-инфикс примет необязательный параметр в качестве своего первого параметра.
Доступные символы для пользовательских операторов в Swift
В Swift пользовательские операторы могут состоять только из следующих символов:
/ = - + * % < > ! & | ^ . ~
Оператор
Учитывая выбор доступных символов, ||| (три трубы, без интервала) не страшны (аналогично двойной трубе ИЛИ в Javascript, которая используется как NCO):
Использование оператора
var a = String?
var z = a ||| "it nil!"
println(z) //Output: it nil!
Определение оператора
operator infix ||| {}
@infix func |||<T> (left: T?, right: T) -> T {
if let l = left { return l }
return right
}
Ответ 3
То, что говорит Венкат, является правильным: нет, но вы можете его определить.
Однако его реализация не идеальна, потому что он забыл использовать @auto_closure
.
Также я считаю, что вы можете перегрузить ||
без необходимости определять новый оператор.
У меня нет компилятора здесь, но я постараюсь дать вам код из памяти:
func |||<T> (maybe: Optional<T>, defaultValue: @auto_closure () -> T) -> T {
if let some = maybe {
return some
}
return defaultValue()
}
Edit: Спасибо Martin R за тестирование этого с помощью компилятора. См. Комментарии. Очевидно, что перегрузка ||
возможна, но может работать не так, как ожидалось, из-за того, что Swift обрабатывает разрешение перегруженных операторов (что недокументировано, и поэтому я понятия не имею, можно ли его обойти или нет). Я изменил функцию выше, чтобы использовать |||
.
Ответ 4
Я написал о пользовательской функции оператора, которая обеспечивает nil-coalescing здесь:
http://ijoshsmith.com/2014/07/24/nil-coalescing-operator-in-swift/
Мой выбор оператора был !!
, который объединяет логический не оператор (!) и оператор разворота (!) для семантики "если не могу развернуть". Кажется, я опоздал на вечеринку, учитывая, что эта тема уже старше месяца. В любом случае, здесь моя реализация в случае, если вам интересно...
operator infix !! {}
@infix func !! <T> (
value: T?,
defaultValue: @auto_closure () -> T)
-> T
{
return value ? value! : defaultValue()
}
Ответ 5
надеюсь, что это поможет вам
-
да, теперь он добавлен в быстрый
-
немного Объяснение
var anumber:Int? = someValue
var banumber = 2
anumber = ( anumber != nil) ? anumber : banumber ------- (a)
println(anumber!)
теперь вместо того, чтобы писать все (а), мы можем просто использовать это →
anumber = anumber ?? banumber
и
Оператор также может использоваться несколько раз в одном выражении.
как
firstNumber ?? secondNumber ?? thirdNumber.
Ответ 6
Вы можете проверить код детской площадки ниже.
import UIKit
var personalSite : String?
let defaultSite = "http://www.google.com"
var website = personalSite ?? defaultSite