Perform Assignment Only If Right Side Is Not Nil

Perform assignment only if right side is not nil

A single expression with the same effect as your code is

funcThatReturnsOptional().map { object.nonOptionalProperty = $0 }

but your code is definitely better readable.

Here the map() method of Optional is used and the closure is
executed only if the function does not return nil.

Shorthand for assignment if nil in Swift?

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()
}

Nil-Coalescing Operator without changing value

You can design your own infix operator:

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

var a = "a"
var b: String? = "b"

a ?= b

print(a) // "b\n"

In Swift, how do I do 'if let' instead of this?

There are several things you can do with an optional value:

var optionalText:String?

...

var text4:String? = optionalText // assign it to another optional variable

var text5 = optionalText // the same, the compiler will infer that text5 is also an optional string

optionalText?.append(" hello") // will only call `append(_:)` on `text` if it's not nil, otherwise this will be ignored

let text6:String = optionalText ?? "It was nil!" // use the coalescing operator

let text7:String = optionalText! // force-unwrap it into a String; if it's nil, your app will crash

// you CANNOT, however, treat it as a non-optional:
let newText = "Hello " + optionalText // this won't compile

// you can unwrap it:
if let text8 = optionalText {
// this code block will ONLY execute if textField.text was not nil
let newString = "Hello "+ text8 // this constant will only work in this block
// in that case, text8 will be of type String (non-optional)
// so it shouldn't be treated as an optional
}
let newString = "Hello "+ text8 // this won't compile

// unwrap it with `guard`:
guard let text8 = optionalText else {
// this code block will ONLY execute if textField.text WAS nil
// and it must return
return
}
let newString = "Hello "+ text8 // this is okay, text8 lives on in case of `guard`

These are the differences between guard let and if let:

  • if let nonOptional = optional {} will assign a value to a non-optional constant by unwrapping an optional value and execute the code block, but only if the optional isn't nil. The non-optional constant will only live inside the if let { } block. Use this if you want to handle both cases (nil or otherwise) and then move on with your code.
  • guard let nonOptional = optional else { } will do the same assignment if possible, but code flow will be different afterwards: it will execute the else block in case the optional value is nil, and that else block will have to quit the scope (return, continue, or break); it must not fall through, i.e. execution must not continue right after the block (the compiler will make sure of that). However, your nonOptional constant will live on after this statement. Use this if your code largely depends on the optional value not being a nil: quit early if the condition fails, and otherwise hold on to the non-optional value and use if for the rest of your enclosing scope.

Btw., you can also use var instead of let if it makes sense, in both cases.

The main purpose of guard is to avoid the "pyramid of doom" type of nested checks:

// pyramid of doom
func doomed() {
if condition1 {
if condition2 {
if condition3 {

// success scenario
print("all good")
// ...

} else {
print("failed condition 3")
return
}
} else {
print("failed condition 2")
return
}
} else {
print("failed condition 1")
return
}
}

// avoiding pyramid of doom
func nonDoomed() {
guard condition1 else {
print("failed condition 1")
return
}

guard condition2 else {
print("failed condition 2")
return
}

guard condition3 else {
print("failed condition 3")
return
}

// success scenario
print("all good")
// ...
}

Without guard, your success scenario is hidden in the middle of nested if statements related to error conditions, making your code difficult to read or edit.

With guard, each error condition is handled separately, and after you get them out of the way, you can go on with the success scenario. With guard let, you can also ensure that all the necessary constants and variables are available for the rest of the scope.

What you seem to need is one of two things:

Optionally unwrap and use your optional:

if let realImage = animal?.img {
let animalImage = UIImage(data: animal!.img!) as UIImage?
saveImageView.image = animalImage
}
// otherwise, saveImageView.image will not be assigned a new value

Simply pass an optional value

saveImageView.image = animal?.img

This should work because the left-hand side and the right-hand side are both UIImage? optionals.

Optional chaining used in left side of assignment in Swift

Sort of like a short-circuiting && operator that stops when it reaches the first false value, optional chaining will stop when it hits the first nil value.

So in an extreme case like container?.cell?.textLabel?.text = "foo", any of container, cell, or textLabel could be nil. If any of them are, that statement is effectively a no-op. Only if the whole chain is non-nil will the assignment happen.

Assign value to variable only if is not null - Kotlin

The operator is called Elvis Operator. It evaluates if x is not null and if that's true, assigns x to y. If it is null, it evaluates the statement after the question mark, returning immediately and therefore leaving y untouched.



Related Topics



Leave a reply



Submit