0

I couldn't understand the difference between a explicitly declared String and an implicitly unwrapped optional string.

For example,

If we initialzse a String explicitly,

let assumedString:String = "Test String"
print(assumedString)

gives the output

"Test String"
"Test String\n"

in playground.

Likewise if we implicitly unwrap an optional string like this,

let assumedString:String! = "Test String"
print(assumedString)

gives the same output

"Test String"
"Test String\n"

And also once we use '!' while initializing, then its value cannot be nil. So We can use the explicit type right?

Then why do we have to use the concept of using '!' (implicitly unwrapping an optional string).

Kindly explain the difference or the use of using '!' with a code example if possible.

Mano
  • 670
  • 1
  • 9
  • 28
  • 1
    Possible duplicate of [Why create “Implicitly Unwrapped Optionals”?](http://stackoverflow.com/questions/24006975/why-create-implicitly-unwrapped-optionals). – Martin R Nov 11 '16 at 07:46
  • A implicit unwrapped **constant** is just nonsense. Further you should not use explicit type annotations unless the compiler tells you. – vadian Nov 11 '16 at 07:47
  • Yeah. In this case the simple answer is that there is no reason at all to use an implicitly unwrapped optional. It will work but serves no purpose over a regular constant. In general, you would only ever use them for variables, not constants. – Dima Nov 11 '16 at 07:49
  • For example, you want to declare a variable and you'll assign value to it later. `var assumedString: String` -> you can't leave it with no value, so you must use implicitly unwrapped optional: `var assumedString: String!`. – Danh Huynh Nov 11 '16 at 07:50

2 Answers2

2

In your example, you're only using let constants. With let constants, you can hardly see the difference between the two. The situation changes.

As you know, all properties in a class must be initialized to some value in the initializer(s). Optional properties is an exception to this rule. They are by default, nil i.e. no value.

I most often use implictly unwrapped optionals is when I have a property that stores a view's height or anything UI related. I always declare those as implicitly unwrapped optionals. e.g.

var myViewsHeight: CGFloat!

override func viewDidLoad() {
    myViewsHeight = self.view.viewWithTag(1).frame.height
}

You obviously can't initialize that variable in init because at init, the views have not been laid out yet! There is no way to know the view's height. You make it an implictly unwrapped optional because you know it will get initialized in viewDidLoad. Another advantage of this is that it makes tracking errors easier. Say your app crashed because if something happened in viewDidLoad and the line that initializes myViewsHeight is not executed, you will know immediately because your app crashes!

You will also see that all IBOutlets are implictly unwrapped optionals, for the same reason - the views can't be assigned at init.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • In this particular case you should declare the variable *always* as non-optional with a default value of 0.0. A frame has always a concrete height. – vadian Nov 11 '16 at 08:01
  • But at the time when I want to use the property (which I'm sure the views have been laid out), 0 would not be useful to me. I would rather make it implicitly unwrapped optional so it crashes and I can then find out what the problem is. @vadian – Sweeper Nov 11 '16 at 08:07
  • For debug reasons it's indeed useful but after solving the problem there is no need to declare a concrete scalar type as an optional. – vadian Nov 11 '16 at 08:10
0
let assumedString:String = "Test String" 

Means you simply define a string constant , but when you write

let assumedString:String! = "Test String" 

means you you are declaring a string of optional type . So,it may contain a value or not . But here you are initialised at the time of declaration of string . So , If you print both will give same output. For more understanding go to below link

Difference between var someString = “Some String”, var someString: String = “Some String”, var someString = “Some String” as string

Community
  • 1
  • 1
Harish Singh
  • 765
  • 1
  • 12
  • 23