Eiko
Eiko

Reputation: 25632

Optional chaining and coalescing incl. function arguments

Optional chaining lets us make decisions on the existence of objects:

var text : String?
let len = text?.lengthOfBytes(using: .utf8) ?? 0

Which will always set len to an integer.

Is something similar possible for non-optional function arguments? Consider the following example, which already is less elegant with the ternary operator.

func length(text: String) -> Int {
    return text.lengthOfBytes(using: .utf8)
}

var text : String?
let len = (text != nil) ? length(text!) : 0

If we keep chaining, it easily gets a mess (and this is what I am actually looking at):

let y = (arg!= nil) ? (foo?.bar(arg!) ?? 0) : 0 // how to improve on this?

Besides, it also starts to get redundant, defining the default value twice.

Is there any more concise solution to the last line?

Upvotes: 1

Views: 795

Answers (3)

w8ite
w8ite

Reputation: 58

The map method is the best approach for this. flatMap may also be of interest.

func length(text: String) -> Int {
    return text.lengthOfBytes(using: .utf8)
}

var text : String?
let len = text.map(length) ?? 0

If you have multiple arguments, you can pretty easily write a function (A?, B?) -> (A, B)?.

Upvotes: 1

Code Different
Code Different

Reputation: 93151

You don't have to limit yourself to optional chaining. Swift provides other language constructs to express this clearly:

let y: Int
if let arg = arg, let foo = foo {
    y = foo.bar(arg)
} else {
    y = 0
}

Upvotes: 0

Oleg Gordiichuk
Oleg Gordiichuk

Reputation: 15512

Take into account that usage of the ?? will do impact on compilation time. In example that you describe, personally I like to use extensions that are clear to use.

extension Optional where Wrapped == String {
    func unwrappedLengthOfBytes(using: String.Encoding) -> Int {
        guard let text = self else {
            return 0
        }
        return text.lengthOfBytes(using: .utf8)
    }
}

Usage:

var text : String?
text.unwrappedLengthOfBytes(using: .utf8)

Upvotes: 0

Related Questions