1

I'm trying to understand how init!() works in Swift. Here's my test:

struct InitTest {
    var text: String
    init!(text: String) {
        self.text = text
    }
}

let testResult = InitTest(text: "Hello!")

For my understanding, testResult should be of type InitTest (unwrapped), but it's actually still InitTest?.

How is init!() different from init?() then?

Robo Robok
  • 21,132
  • 17
  • 68
  • 126

1 Answers1

1

InitTest(text: "Hello!") returns an implicitly unwrapped optional, which is an optional that is unwrapped if necessary. For example you can access its properties without explicit unwrapping

let string = InitTest(text: "Hello!").text

or pass it to functions taking a (non-optional) InitTest argument:

func foo(_ x: InitTest) { }
foo(InitTest(text: "Hello"))

But the assignment

let testResult = InitTest(text: "Hello!")

makes testResult a regular ("strong") optional, see SE-0054 Abolish ImplicitlyUnwrappedOptional type and Implicitly unwrapped optional assign in Xcode 8:

If the expression can be explicitly type checked with a strong optional type, it will be.

Actually I cannot think of a good reason to define an init!() method.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • `let text = InitTest(text: "Hello!").text` works as expected, but `let testResult = InitTest(text: "Hello!"); let text = testResult.text` produces an error: `Value of optional type 'InitTest?' not unwrapped; did you mean to use '!' or '?'?`. Why is `testResult` still optional `InitTest`? – Robo Robok Jul 08 '17 at 14:45
  • @RoboRobok: That's what I tried to explain at *"But the assignment ... makes testResult a regular ("strong") optional"* and in https://stackoverflow.com/questions/39633481/implicitly-unwrapped-optional-assign-in-xcode-8. It is a consequence of SE-0054. – Martin R Jul 08 '17 at 14:47
  • Sorry, I was too excited and didn't notice your explanation :D – Robo Robok Jul 08 '17 at 14:49
  • Thank you for help, once again! – Robo Robok Jul 08 '17 at 14:57