The Apple Swift Programming Language guide mentions the existence of the init! initializer, but does not provide any example for it. (Search for init! in this page)
I understand the use of a normal failable initializer declared with init?, but I fail to get the need of this other version. What is it needed for? Can somebody provide an example?
It makes a difference in two situations:
If you write
then init? will not compile because init? returns an optional; init! will compile but crash if the init method returns nil.
If you write
then it will compile in either case, and it will not crash in either case. The difference is that in one case x has type myclass? and in the other case type myclass! with the obvious differences in behaviour.
If you write one of the following two:
then it doesn't matter whether init! or init? was used, because either can be assigned to an optional without crashing.
I'm going to take a stab at this even though this question has been around for a while because I think some example source code would be useful for understanding what
init!
is for (at least it was for me).An implicitly unwrapped optional provides two things of value:
?
' at the end of your optional variables), andnil
only once, and thereafter (as long as it is non-nil
) use its unwrapped (i.e. direct) value.The important part though is that an implicitly unwrapped optional is still an optional, which means it can be tested for
nil
.Now, as to the utility of the
init!
-failable initializer, we can use it to get the two things I listed above (convenience and runtime efficiency), while still allowing aninit
function to fail (i.e. to returnnil
). This can happen, as others have noted, by calling into Objective-C API, but it can also happen directly from code you might choose to write. Here's an example:In this example, I gave myself a way to fail the initialization of
class A
, and yes, could as easily have done it with aninit?
method, but when I create an object of typeA
I'll probably only ever need to test that the initialization succeeded or failed once--after all, I either created an A or I didn't--and afterwards if it's notnil
I'll just want to use the direct value. So in this case, using theinit!
-failable initializer turns out to be pretty handy.The init initializer is the same like the constructor for classes in other languages. It sets initial values and performs some initial Operations (like checking wether a value is to big etc.). Interesting: It also takes Parameters and can be overloaded.
Example:
So when when you call the struct it returns different values depending on your call parameters.
For more info: http://www.informit.com/articles/article.aspx?p=2246797
Good question Matteo, I´m looking answer for the same question because init! don´t have sense (if it always init an object and we don´t need optional), but I haven´t found any clear answer.
I think that it´s because Apple haven´t finished his work: "...own Objective-C classes, and classes in frameworks that have not yet been audited, initializers are imported as init! ..."
Perhaps be util for you, the text in "Interacting with Objective-C APIs"(Apple)
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html
This serves two purposes:
When importing Cocoa APIs that Swift doesn't know about. If Swift does not know if an initializer can return nil or not, it annotates it with ! so that the developer knows there might be a nil hiding there, without forcing the dev to test for nil if there's actually no reason to.
For the same reasons implicitly-unwrapped optionals are used in other contexts (you may be willing to trade compile-time safety for added convenience in some cases).
I belive it's absolutely the same use of
!
as in optionals.init?
will return an optional.init!
will return an implicitly unwrapped optional.Implicitly unwrapped optionals are needed for calling Obj-C APIs where you are not sure whether it can return an optional or not. So you use an implicitly unwrapped optional and it behaves like a non-optional type but it will crash if an optional is returned.
Note that when Swift was introduced most Obj-C frameworks returned only implicitly unwrapped optionals but currently a lot of them return optionals or non-optional types because Apple is going through the code and checks whether they can return an optional or not.
init!
is needed everywhere where Apple hasn't tagged the initializers correctly yet.