Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
141 views
in Technique[技术] by (71.8m points)

ios - What is the difference between String? and String! (two ways of creating an optional variable)?

In The Swift Programming Language (book of Apple) I've read that you can create optional variables in 2 ways: using a question mark (?) or by using an exclamation mark (!).

The difference is that when you get the value of an optional with (?) you have to use an exclamation mark every time you want the value:

var str: String? = "Question mark?"
println(str!) // Exclamation mark needed
str = nil    

While with an (!) you can get it without a suffix:

var str: String! = "Exclamation mark!"
println(str) // No suffix needed
str = nil

What is the difference and why are there 2 ways if there is no difference at all?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The real benefit to using implicitly unwrapped optionals (declared with the !) is related to class initialisation when two classes point to each other and you need to avoid a strong-reference cycle. For example:

Class A <-> Class B

Class A's init routine needs to create (and own) class B, and B needs a weak reference back to A:

class A {
    let instanceOfB: B!
    init() {
        self.instanceOfB = B(instanceOfA: self)
    }
}

class B {
    unowned let instanceOfA: A
    init(instanceOfA: A) {
        self.instanceOfA = instanceOfA
    }
}

Now,

  • Class B needs a reference to class A to be initialised.
  • Class A can only pass self to class B's initialiser once it's fully initialised.
  • For Class A to be considered as initialised before Class B is created, the property instanceOfB must therefore be optional.

However, once A's been created it would be annoying to have to access instanceOfB using instanceOfB! since we know that there has to be a B

To avoid this, instanceOfB is declared as an implicity unwrapped optional (instanceOfB!), and we can access it using just instanceOfB. (Furthermore, I suspect that the compiler can optimise the access differently too).

An example of this is given on pages 464 to 466 of the book.

Summary:

  • Use ? if the value can become nil in the future, so that you test for this.
  • Use ! if it really shouldn't become nil in the future, but it needs to be nil initially.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...