Swift unwrapping Optional value by "?" and "!" [duplicate] - swift

This question already has an answer here:
What is the difference when change to use optional chaining replace forced unwrapping in swift?
(1 answer)
Closed 5 years ago.
What are the differences when i unwrap Optional value by ? and !
If there is Class name A and there is a property name proA
Then if i make an instance like this
var a:A? = A()
a?.proA
a!.proA
I can approach property 'proA' two ways above. I know I cannot get value if I use a.proA because a is a Optional Type.
Also, I know a!.proA can get value because it unwrap the value in force
And what is a?.proA?
What are the differences between a?.proA and a!.proA

As you stated, ! forcefully unwraps the optional.
var a: A? = A()
a!.prop
However, what happens if the optional was never assigned a value, which means it's nil?
var a: A?;
a!.pop
You get a Swift runtime error (think of it as the equivalent of a null pointer exception in other languages e.g. Java).
On the other hand, if you use ?, you can take advantage of optional chaining. This allows you to gracefully traverse optional properties without fear of causing a runtime error. If some intermediate property along the chain is nil, the whole expression will return nil.
var a: A?;
a?.pop //returns nil, no runtime error

Related

What is the point of using an "Implicitly Unwrapped Optional" as a function parameter type?

I go over some code written by other developers and now and then I encounter signatures like this one:
func didReceiveLogMessage(_ message: String!)
Would it be safe to convert this parameter type to String instead of String! ?
Basically never declare a custom function parameter as implicit unwrapped optional. Don't.
This is a pre Swift 3 legacy syntax only for Objective-C and Core Foundation compatibility.
It's absolutely safe and even highly recommended to remove the exclamation mark. However if you really need an optional use a regular optional (?)
This gives no value. It actually adds complexity as even an Inmplicitly unwrapped optional as such counts as an optional, meaning it can be nil (but will crash). a regular String can't be nil

Why is it necessary to coerce from Optional to Any? [duplicate]

This question already has answers here:
Why can't you assign an Optional to a variable of type `Any` without a warning?
(5 answers)
Why do we need to explicitly cast the optional to Any?
(1 answer)
Closed 4 years ago.
I have seen several questions regarding "expression implicitly coerced from an Optional to Any"(such as this and this), but I did not find one explaining the reason why Optional is not "included" in Any, since, according to the Apple's Swift Standard Library, Optional is a generic enum type.
Any parameters are expected for the print function, so providing Optional would give the warning message. However, since Optional is an enum type, shouldn't it be an Any type as well? Why is Optional, as an enum type, not part of the Any type such that the compiler needs to convert Optional to Any?
The purpose of Optional is to prevent you from accidentally calling methods on or accessing properties of variables which are nil.
You are right that Optional can be assigned to Any. Anything can be assigned to Any. But look what happens now! I have transformed a value that can be nil into a non-optional type Any! If somehow this value is passed to somewhere else and some other programmer (or you in the future) would assume that it has a non-nil value.
Therefore, the compiler warning is there to remind you that you may have forgotten to unwrap your optionals.

Swift variable declare with optional(?) or force unwrap(!) different? [duplicate]

This question already has answers here:
What is the difference between String? and String! (two ways of creating an optional variable)?
(7 answers)
Closed 4 years ago.
what is different, when we declare new variable post fix with either ? or !
ex:
class Car{
var gear : Int!
var color : String?
}
and I couldn`t find any resource regard of this problem
Foo? is an optional. Foo! is an implicitly unwrapped optional.
This section of the language guide explains what implicitly unwrapped optionals are:
Sometimes it’s clear from a program’s structure that an optional will always have a value, after that value is first set. In these cases, it’s useful to remove the need to check and unwrap the optional’s value every time it’s accessed, because it can be safely assumed to have a value all of the time.

as! vs as operator in Xcode 6.3 in Swift

Swift changed a lot with Xcode 6.3. I had to replace dozens of places in each of my app as -> as!. Why, what are the rules now?
Prior to Swift 1.2, the as operator could be used to carry out two different kinds of conversion, depending on the type of expression being converted and the type it was being converted to:
Guaranteed conversion of a value of one type to another, whose success can be verified by the Swift compiler. For example, upcasting (i.e., converting from a class to one of its superclasses) or specifying the type of a literal expression, (e.g., 1 as Float).
Forced conversion of one value to another, whose safety cannot be guaranteed by the Swift compiler and which may cause a runtime trap. For example downcasting, converting from a class to one of its subclasses.
Swift 1.2 separates the notions of guaranteed conversion and forced conversion into two distinct operators. Guaranteed conversion is still performed with the as operator, but forced conversion now uses the as! operator. The ! is meant to indicate that the conversion may fail. This way, you know at a glance which conversions may cause the program to crash.
Source: https://developer.apple.com/swift/blog/?id=23
The practical difference is this:
var optionalString = dict.objectForKey("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.objectForKey("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.objectForKey("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".
println(string)
}
According to the release notes:
The notions of guaranteed conversion and “forced failable” conversion
are now separated into two operators. Forced failable conversion now
uses the as! operator. The ! makes it clear to readers of code that
the cast may fail and produce a runtime error. The “as” operator
remains for upcasts (e.g. “someDerivedValue as Base”) and type
annotations (“0 as Int8”) which are guaranteed to never fail.

When do you use obj!.attr and obj?.attr?

If obj not exist obj? generate a nil so obj?.attr too.
If obj is nil then obj!.attr crashes.
But if I am sure obj at that certain point of the code always exist, than for me it seems it is independent which one to use. Am I right? What coding styles do you use?
In my very own opinion, if you're really sure that obj exists, you can use ! or ? either. They produce the same effect on an existing object. The only issue is the compiler: sometimes it's fine to use ! instead of ?, sometimes not.
Anyway, if you want to read further on this, give a chance to the free book by Apple "The Swift Programming Language": these things are very well explained there!
If obj exists, obj?.attr returns an optional type even if attr is not an optional. On the other hand, obj!.attr will be whatever type attr is, so no additional unwrapping is needed if attr is a non-optional.
Consider this example:
class Person {
var age = 37
}
var fred: Person? = Person()
let ageNextYear = fred?.age + 1 // error: value of optional type Int? not unwrapped
let ageLastYear = fred!.age - 1 // this works
You use ? when you create a variable with out giving it a value, meaning it can exist and be used in an unitialized state. And as long as it is not initialized it has no type associated to it.
It has nothing do with the value being nil or not.
As Swift is type safe it requires all variables and constant to always hold a value by default, meaning they have a type. So defining something with ? or ! puts a wrapper around it.
enum Optional {
case None
case Some(T)
}
As you see it either has a type or not. Being nil (if possible for a type) or not has not much to do with it. But everything that does not have a type associated is usually nil.
When you then deal with the value of a variable that was declared as being optional, you need to unwrap it by using ! or else you would use the enumeration showed above.
Unwrapping means that you can assert that it does hold a value meaning it has a type. It takes it out of the enumeration and presents the value it has as a type.
Regarding coding style you usually only need to declare something as ? when you work with C or Objective-C APIs. In pure Swift you will usually not declare something as being optional.
You might need to use ! even in pure swift when something might not be defined. For example you have multi-dimensional array that were initialized as being empty. This is because of how Swift currently handle true multi-dimensional objects where the higher dimensions are implicit optionals.
TL;DR: Don't use ? at all unless you are forced to when dealing with C/Obj-C APIs. When using a value of a variable declared with ? always use ! to refer to the value and never ?.
Some links that explains what happens in more detail:
http://www.drewag.me/posts/what-is-an-optional-in-swift
http://www.drewag.me/posts/uses-for-implicitly-unwrapped-optionals-in-swift