62

I want to use an Optional variable with the ternary conditional operator but it is throwing error this error: optional cannot be used as boolean. What am I doing wrong?

var str1: String?
var myBool:Bool
myBool = str1 ? true : false
zekel
  • 9,227
  • 10
  • 65
  • 96
Yashwanth Reddy
  • 639
  • 1
  • 5
  • 4

6 Answers6

85

You can not assign string value to bool but You can check it str1 is nil or not like this way :

myBool = str1 != nil ? true : false
print(myBool)

It will print false because str1 is empty.

alessionossa
  • 923
  • 2
  • 15
  • 41
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
70

Nil Coalescing Operator can be used as well. The code below uses the ternary conditional operator and forced unwrapping (a!) to access the value wrapped inside a when a is not nil, and to return b otherwise

Normal Ternary Operator :

output = a != nil ? a! : b Apple Developer Link : Please refer to Demo Link

In Swift 1.2 & 2, above line of code is replaced by a shorter format:

output = a ?? b

Demo Link : The nil coalescing operator (a ?? b) unwraps an optional a if it contains a value, or returns a default value b if a is nil.

Abhijeet
  • 8,561
  • 5
  • 70
  • 76
5

This even works well if the value you want is a property or result of a function call on an optional (in Swift 3.0):

return peripheral?.connected ?? false
Robert Atkins
  • 23,528
  • 15
  • 68
  • 97
  • that's not answering the same question, because you assume we want the value - if it exists, and nil otherwise. While we want two different expressions - based on an arbitrary conditionals. something like a>3 ? (4+7) : (6/4) in C. – Motti Shneor Jul 30 '17 at 13:33
5

Ternary operators operate on three targets. Like C, Swift has only one ternary operator, the ternary conditional operator (a ? b : c).

Example usage on tableView -

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return section == 2 ?  4 :  1
}

indicates if section equal to 2 then it return 4 otherwise 1 on false.

Jack
  • 13,571
  • 6
  • 76
  • 98
2

To add on the already very good answers, sometimes you need the convenience of the ternary operator but also need to perform changes on the wrapped value, such as;

var fullName = lastName != nil ? "\(firsName) \(lasName!)" : firstName

But you don't want to force unwrap (even though this situation would be fine).

Then you can actually use Optional.map:

var fullName = lastName.map({ "\(firstName) \($0)" }) ?? firstName

The completion block passed to .map is only called if the wrapped value ($0) is not nil. Otherwise, that function just returns nil, which you can then easily coalesce with the ?? operator.

Skwiggs
  • 1,348
  • 2
  • 17
  • 42
0

In case the comparison is based on some condition

 let sliderValue = Float(self.preferenceData.getLocationRadius().characters.count > 1 ?self.preferenceData.getLocationRadius():"0.1")

Here the function getLocationRadius() returns a String. One more thing if we don't put a space between 1 and ? it results in an syntax error

Muhammad Nayab
  • 1,612
  • 14
  • 14