2016-10-05 2 views
3

Я пытаюсь создать нуль-сливающихся оператор присваивания в Swift 3. Другими словами, вместо этого:Null-коалесцирующий в Swift 3

x = x ?? y 

Я хочу это:

x ??= y 

Swift 3, похоже, не нравится моему оператору. Вот его определение:

infix operator ??= : AssignmentPrecedence 
func ??=(lhs: inout Any?, rhs: @autoclosure() -> Any?) { 
    if lhs != nil { return } 
    lhs = rhs() 
} 
var x = 3 
x ??= 7 // Cannot convert value of type 'Int' to expected argument type 'inout Any?'. 

Я сделал это без @autoclosure тоже. Я понимаю, что группа приоритетов AssignmentPrecedence уже содержит объявление assignment, так что это вряд ли будет проблемой.

Как это сделать в Swift 3?

+1

Возможно, вам придется отметить [это] (https://github.com/apple/swift-evolution/blob/master/proposals/0024-optional-value-setter.md) при обсуждении этой темы. – OOPer

+0

Очень хороший момент, но, похоже, вы уже это заметили. :) –

+1

Несомненно, поэтому я также отмечаю, что, когда я предложил что-то очень похожее на 'ClosedRange' в эпоху Swift 1.x на старых форумах разработчиков Dev, ответ от команды Swift был похож на холодный и негативный. Но, как видите, теперь у Swift 3 есть это. Swift 5 будет иметь этот оператор в стандартной библиотеке, если мы сможем достаточно хорошо обжаловать его варианты использования. – OOPer

ответ

5

Во-первых, сделать оператор родовое вместо использования Any:

infix operator ??= : AssignmentPrecedence 
func ??=<T>(lhs: inout T?, rhs: @autoclosure() -> T?) { 
    if lhs != nil { return } 
    lhs = rhs() 
} 

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

var x: Int? = 3 
x ??= 7 
+1

На самом деле, я знал это. Очень глупо от меня. Тем не менее, я надеюсь, что это поможет кому-то в будущем. –

+0

Я глубоко удивлен, что этот оператор не включен в стандартную библиотеку Swift по умолчанию. Кажется, это так очевидно. –

+3

Обратите внимание, что параметр inout копируется в функцию и затем копируется обратно при возврате (при условии оптимизации компилятора). Поэтому, даже если lhs не равен нулю, ему будет присвоено новое значение, и будут вызваны наблюдатели свойств. Это делает оператора менее полезным, чем можно было бы подумать. –