Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downcasting optionals in Swift: as? Type, or as! Type?

Given the following in Swift:

var optionalString: String? let dict = NSDictionary() 

What is the practical difference between the following two statements:

optionalString = dict.objectForKey("SomeKey") as? String 

vs

optionalString = dict.objectForKey("SomeKey") as! String? 
like image 410
sdduursma Avatar asked Sep 07 '14 09:09

sdduursma


People also ask

What is difference between as As and As in Swift?

Type casting in Swift is implemented with the is and as operators. is is used to check the type of a value whereas as is used to cast a value to a different type.

What is Downcasting in Swift?

Swift Language Type Casting Downcasting operator attempts to cast to a subtype. It can fail, therefore it returns an optional.

What is Upcasting and Downcasting?

Upcasting (Generalization or Widening) is casting to a parent type in simple words casting individual type to one common type is called upcasting while downcasting (specialization or narrowing) is casting to a child type or casting common type to individual type.

What is any type in Swift?

The Any type represents values of any type, including optional types. Swift gives you a warning if you use an optional value where a value of type Any is expected. If you really do need to use an optional value as an Any value, you can use the as operator to explicitly cast the optional to Any , as shown below.

How do I cast an optional value to any in Swift?

Swift gives you a warning if you use an optional value where a value of type Any is expected. If you really do need to use an optional value as an Any value, you can use the as operator to explicitly cast the optional to Any, as shown below.

How do you use any in Swift?

The Any type represents values of any type, including optional types. Swift gives you a warning if you use an optional value where a value of type Any is expected. If you really do need to use an optional value as an Any value, you can use the as operator to explicitly cast the optional to Any, as shown below.

What is type casting in Swift?

Type casting is a way to check the type of an instance, or to treat that instance as a different superclass or subclass from somewhere else in its own class hierarchy. Type casting in Swift is implemented with the is and as operators.

What are optionals in Swift 4?

Swift 4 also introduces Optionals type, which handles the absence of a value. Optionals say either "there is a value, and it equals x" or "there isn't a value at all". An Optional is a type on its own, actually one of Swift 4’s new super-powered enums.


2 Answers

The practical difference is this:

var optionalString = dict["SomeKey"] as? String 

optionalString will be a variable of type String?. If the underlying type is something other than a String this will harmlessly just assign nil to the optional.

var optionalString = dict["SomeKey"] as! String? 

This says, I know this thing is a String?. This too will result in optionalString being of type String?, but it will crash if the underlying type is something else.

The first style is then used with if let to safely unwrap the optional:

if let string = dict["SomeKey"] as? String {     // If I get here, I know that "SomeKey" is a valid key in the dictionary, I correctly     // identified the type as String, and the value is now unwrapped and ready to use.  In     // this case "string" has the type "String".     print(string) } 
like image 165
vacawama Avatar answered Sep 22 '22 23:09

vacawama


as? Types - means the down casting process is optional. The process can be successful or not(system will return nil if down casting fails).Any way will not crash if down casting fails.

as! Type? - Here the process of down casting should be successful (! indicates that) . The ending question mark indicates whether final result can be nil or not.

More info regarding "!" and "?"

Let us take 2 cases

  1. Consider:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell 

    Here we don't know whether the result of down casting of cell with identifier "Cell" to UITableViewCell is success or not. If unsuccessful then it returns nil( so we avoid crash here). Here we can do as given below.

    if let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell {     // If we reached here it means the down casting was successful } else {     // unsuccessful down casting } 

    So let us remember it like this - If ? it means we are not sure whether value is nil or not (question mark comes when we don't know things).

  2. Contrast that to:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell.  

    Here we tell the compiler that down casting should be successful. If it fails the system will crash. So we give ! when we are sure that value is non nil.

like image 35
jishnu bala Avatar answered Sep 20 '22 23:09

jishnu bala