user842225
user842225

Reputation: 5989

'?'must be followed by a call, member lookup or subscript

I have defined a String type computed property:

var name : String? {
   //an optional variable
   var theName : String?

  if SOME_CONDITION {
     theName = “I have a name”
 }
 //ERROR: '?'must be followed by a call, member lookup or subscript
 return theName?
}

I want to return whatever theName is, if it is nil, return nil. So I use return theName? , I don’t want to have runtime error. The compiler however raise an error '?'must be followed by a call, member lookup or subscript Why? How to get rid of it.

Upvotes: 1

Views: 1937

Answers (2)

Nikita Kukushkin
Nikita Kukushkin

Reputation: 15138

Adding ? to the end of a type makes it Optional. Adding ? to the end of an optional variable invokes Optional Chaining.

You specify optional chaining by placing a question mark (?) after the optional value on which you wish to call a property, method or subscript if the optional is non-nil. This is very similar to placing an exclamation mark (!) after an optional value to force the unwrapping of its value. The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.

To reflect the fact that optional chaining can be called on a nil value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a non-optional value. You can use this optional return value to check whether the optional chaining call was successful (the returned optional contains a value), or did not succeed due to a nil value in the chain (the returned optional value is nil).

Specifically, the result of an optional chaining call is of the same type as the expected return value, but wrapped in an optional. A property that normally returns an Int will return an Int? when accessed through optional chaining.


Example

class Foo {
    var bar: Int
}

var x: Foo? // ? is attached to type Foo, it makes x an optional variable

let y: Int? = x?.bar // ? is attached to the variable x, this is optional chaining, it makes .bar return Int?

Upvotes: 0

Michal
Michal

Reputation: 15669

What about this? Looks more elegant to me:

var name : String? {
    let condition = true // your own condition here of course
    return condition ? "I have a name" : nil
}

The problem in your code:

var name : String? {
    var theName : String?

    let condition = true // your own condition here of course
    if condition {
        theName = "I have a name"
    }

    return theName // get rid of the ? here
}

The field theName is already optional, no need to add another ? there.

Why is my proposed solution not an alternate solution:

The construct I used is called ternary operator:

The ternary conditional operator is a special operator with three parts, which takes the form question ? answer1 : answer2. It is a shortcut for evaluating one of two expressions based on whether question is true or false. If question is true, it evaluates answer1 and returns its value; otherwise, it evaluates answer2 and returns its value.

It behaves like the if statement but is suitable here as it is shorter and thus clearer to read: Depending on the condition, the value is either theName or nil. You really don't need to assign the value to any other variable, because, afterall, you are computing it, so might as well simply return it as the condition decides, what the value is.

Upvotes: 2

Related Questions