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

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.

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 use T! instead of T as function parameter and return type? [duplicate]

This question already has answers here:
In Swift, what does the ! symbol mean in a function signature?
(2 answers)
Closed 3 years ago.
In JavaScriptCore, I saw most of functions declared T! as parameter type and return type. Since T! assumes non-nil when pass in and return, why not just declare T as type?
e.g.
func evaluateScript(_ script: String!) -> JSValue!
why not just
func evaluateScript(_ script: String) -> JSValue
This indicates that an ObjC API has not yet been audited for nullability, and does not have nullability annotations applied. Without nullability annotations, the compiler doesn't know whether the values are optional or not. The default behavior in that case is to make them all ! types, and leave the question to the caller (the only other possible approach would be to make everything ? types, which would be extremely inconvenient to work with).
When Apple annotates the header, the ! will go away.
In the meantime, it's up to you to check the documentation to ensure the return values cannot be nil before using them directly.
In this particular case, the underlying JSEvaluateScript can in fact return nil:
#result The JSValue that results from evaluating script, or NULL if an exception is thrown.
So you do need to check it. There's just no way for the compiler to know that currently.

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 unwrapping Optional value by "?" and "!" [duplicate]

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

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