Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing optional variable

Tags:

swift

People also ask

What is optional variable?

It means we call method without passing the arguments. The optional parameter contains a default value in function definition. If we do not pass optional argument value at calling time, the default value is used. Thera are different ways to make a parameter optional.

How do I remove optional text in Swift?

If my assumption is incorrect, then one quick hack you can quickly do to get rid of the "Optional" in the text is to change your strings to force unwrap item , like so: theYears. text = "\(item!. experience)" .


You have to understand what an Optional really is. Many Swift beginners think var age: Int? means that age is an Int which may or may not have a value. But it means that age is an Optional which may or may not hold an Int.

Inside your description() function you don't print the Int, but instead you print the Optional. If you want to print the Int you have to unwrap the Optional. You can use "optional binding" to unwrap an Optional:

if let a = age {
 // a is an Int
}

If you are sure that the Optional holds an object, you can use "forced unwrapping":

let a = age!

Or in your example, since you already have a test for nil in the description function, you can just change it to:

func description() -> String {
    return age != nil ? "\(name) is \(age!) years old." : "\(name) hides his age."
}

To remove it, there are three methods you could employ.

  1. If you are absolutely sure of the type, you can use an exclamation mark to force unwrap it, like this:

    // Here is an optional variable:

    var age: Int?

    // Here is how you would force unwrap it:

    var unwrappedAge = age!

If you do force unwrap an optional and it is equal to nil, you may encounter this crash error:

enter image description here

This is not necessarily safe, so here's a method that might prevent crashing in case you are not certain of the type and value:

Methods 2 and three safeguard against this problem.

  1. The Implicitly Unwrapped Optional

    if let unwrappedAge = age {

    // continue in here

    }

Note that the unwrapped type is now Int, rather than Int?.

  1. The guard statement

    guard let unwrappedAge = age else { // continue in here }

From here, you can go ahead and use the unwrapped variable. Make sure only to force unwrap (with an !), if you are sure of the type of the variable.

Good luck with your project!


For testing/debugging purposes I often want to output optionals as strings without always having to test for nil values, so I created a custom operator.

I improved things even further after reading this answer in another question.

fileprivate protocol _Optional {
    func unwrappedString() -> String
}

extension Optional: _Optional {
    fileprivate func unwrappedString() -> String {
        switch self {
        case .some(let wrapped as _Optional): return wrapped.unwrappedString()
        case .some(let wrapped): return String(describing: wrapped)
        case .none: return String(describing: self)
        }
    }
}

postfix operator ~? { }
public postfix func ~? <X> (x: X?) -> String {
    return x.unwrappedString
}

Obviously the operator (and its attributes) can be tweaked to your liking, or you could make it a function instead. Anyway, this enables you to write simple code like this:

var d: Double? = 12.34
print(d)     // Optional(12.34)
print(d~?)   // 12.34
d = nil
print(d~?)   // nil

Integrating the other guy's protocol idea made it so this even works with nested optionals, which often occur when using optional chaining. For example:

let i: Int??? = 5
print(i)              // Optional(Optional(Optional(5)))
print("i: \(i~?)")    // i: 5

Update

Simply use me.age ?? "Unknown age!". It works in 3.0.2.

Old Answer

Without force unwrapping (no mach signal/crash if nil) another nice way of doing this would be:

(result["ip"] ?? "unavailable").description.

result["ip"] ?? "unavailable" should have work too, but it doesn't, not in 2.2 at least

Of course, replace "unavailable" with whatever suits you: "nil", "not found" etc


To unwrap optional use age! instead of age. Currently your are printing optional value that could be nil. Thats why it wrapped with Optional.


In swift Optional is something which can be nil in some cases. If you are 100% sure that a variable will have some value always and will not return nil the add ! with the variable to force unwrap it.

In other case if you are not much sure of value then add an if let block or guard to make sure that value exists otherwise it can result in a crash.

For if let block :

if let abc = any_variable {
 // do anything you want with 'abc' variable no need to force unwrap now.
}

For guard statement :

guard is a conditional structure to return control if condition is not met.

I prefer to use guard over if let block in many situations as it allows us to return the function if a particular value does not exist. Like when there is a function where a variable is integral to exist, we can check for it in guard statement and return of it does not exist. i-e;

guard let abc = any_variable else { return }

We if variable exists the we can use 'abc' in the function outside guard scope.


age is optional type: Optional<Int> so if you compare it to nil it returns false every time if it has a value or if it hasn't. You need to unwrap the optional to get the value.

In your example you don't know is it contains any value so you can use this instead:

if let myAge = age {
    // there is a value and it's currently undraped and is stored in a constant
}
else {
   // no value
}