1

I run these codes in the playground, but I get a compile error with

a.b.b = 3

but it runs well at the next line. What's the difference between these two? When should I use the '!' explicitly and when it's not necessary?

Here are the codes:

class A {
    var a = 1
    var b = B()
}

class B {
    var b = 2
}

var a:A! = A()

a.b.b = 3 // will get a compile error
print(a.b.b) // runs well, print 2
a?.b.b = 3 // runs well
print(a.b.b) // runs well, print 3

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
richar lee
  • 11
  • 1
  • Your code runs just fine. What is the error you're getting? – Alladinian Mar 06 '20 at 15:45
  • The issue you're probably seeing is due to problems in Playgrounds. If you compile this elsewhere it runs fine. That said, you almost certainly should not be using an implicitly unwrapped optional. They are used to solve certain late-initialization problems, and in some cases are used to deal with unannotated Objective-C bridging. The kind of situation you've described here would almost certainly not be a proper use of them (I don't know of any cases where they're appropriate as a local variable). – Rob Napier Mar 06 '20 at 16:00
  • In your code neither the exclamation mark nor the type annotation itself is necessary. You make it even worse: You annotate a non-optional as (implicit unwrapped) optional. Avoid optionals as much as possible. And annotate types only if the compiler asks you to do it. – vadian Mar 06 '20 at 16:05
  • @Alladinian maybe it's just a problem in the playground. I think they are the same, so I get confused when meeting the error. Thanks for the reply. – richar lee Mar 07 '20 at 06:38
  • @RobNapier Thanks for the reply. It seems that the problem in the playground makes me confused. – richar lee Mar 07 '20 at 06:40
  • @vadian Thanks for the reply. It seems that the problem in the playground makes me confused. – richar lee Mar 07 '20 at 06:40

1 Answers1

3

Welcome to Stackoverflow. Let's try to answer your questions one by one.

What's the difference between these two? a.b.b = 3 and print(a.b.b)

If this is what you mean, the first one causes an error on Playground,

expression failed to parse, unknown error

then actually there's no difference. But if you wanna know why this happens, it must be a Playground issue. Because this expression should not cause a compile-time error in Xcode (project).

To solve that in Playground, you need to breakdown your expression, like so:

let bOfA = a.b
bOfA.b = 3

Voila! Problem solved!

Also, this issue might be somehow connected with the Xcode error:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions


When should I use the '!' explicitly and when it's not necessary?

You use that ! if you are sure that your object is has a value. ! automatically unwraps the object, without having to check whether it is nil or not.

When it's not necessary? Well, as much as possible, you shouldn't practice force-unwrapping. Read on safe unwrapping optionals for more info. There are lots of resources out there about it.

  1. Swift safely unwrapping optinal strings and ints
  2. https://learnappmaking.com/swift-optionals-how-to/
  3. https://forums.developer.apple.com/thread/45469
Glenn Posadas
  • 12,555
  • 6
  • 54
  • 95
  • 1
    Thanks for this. The most confused me is the first answer. So it seems a playground problem. And the other answers are so useful too. Thanks a lot – richar lee Mar 07 '20 at 06:37