Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shorthand for assignment if nil in Swift?

Tags:

swift

if x == nil {
    x = y
}

I know the statement above can be rewritten as:

x = x ?? y

But x ??= y is not accepted by compiler. Is there a shorthand not to repeat x?

like image 447
yzyzsun Avatar asked Dec 03 '15 07:12

yzyzsun


People also ask

What does ~= mean in Swift?

The expression represented by the expression pattern is compared with the value of an input expression using the Swift standard library ~= operator. The matches succeeds if the ~= operator returns true . By default, the ~= operator compares two values of the same type using the == operator.

What is nil type in Swift?

In Swift, nil means the absence of a value. Sending a message to nil results in a fatal error. An optional encapsulates this concept. An optional either has a value or it doesn't. Optionals add safety to the language.

How do you say or in Swift?

Swift supports the three standard logical operators found in C-based languages: Logical NOT ( !a ) Logical AND ( a && b ) Logical OR ( a || b )

What does mean Swift?

1 : moving or capable of moving with great speed a swift runner. 2 : occurring suddenly or within a very short time a swift transition.


3 Answers

Check this out, put the following in global code space(In your Extensions.swift maybe). This creates a custom operator you can use throughout your entire project.

Swift 2

infix operator ??= {}
func ??= <T>(inout left: T?, right: T) {
    left = left ?? right
}

Swift 3

infix operator ??=
func ??= <T>(left: inout T?, right: T) {
    left = left ?? right
}

Usage:

var foo: String? = nil
var bar = "Bar"
foo ??= bar
print("Foo: \(bar)")

Hope this helps :)

like image 96
Laffen Avatar answered Oct 30 '22 22:10

Laffen


Laffen’s answer is great. However, it is not exactly equivalent to x = x ?? y as the right hand side is always evaluated with their definition of ??= as opposed to the standard ?? operator.

If you want to have this behavior too, @autoclosure is here to help:

infix operator ??=
func ??=<T>(left: inout T?, right: @autoclosure () -> T) {
    left = left ?? right()
}
like image 41
idmean Avatar answered Oct 30 '22 22:10

idmean


This code works in playground:

var x: Int? = nil
let y = 5
x = x ?? y // x becomes 5

and

var x: Int? = 6
let y = 5
x = x ?? y // x stays 6 

By the way here are some variants of checking for nil:

if x != nil {
    // classic
}

if x != .None {
    // nil in Swift is enum with value .None
}

if let _x = x {
    // if you need it's value
}
if let _ = x {
    // if you don't need it's value
}

UPD: code for project - copy and run it:

var x: Int? = nil
let y = 5
x = x ?? y
print (x)
x = 7
x = x ?? y
print (x)
like image 39
katleta3000 Avatar answered Oct 31 '22 00:10

katleta3000