String之间有什么区别?和字符串! (创建可选变量的两种方法)? [英] What is the difference between String? and String! (two ways of creating an optional variable)?
问题描述
在 Swift编程语言(Apple的书)我读过你可以用两种方式创建可选变量:使用问号(?)或使用感叹号(!) 。
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
什么是差异,为什么有2种方法,如果没有任何区别?
What is the difference and why are there 2 ways if there is no difference at all?
推荐答案
使用隐式解包方案的真正好处(用!声明)与类初始化有关,当两个类相互指向并且您需要避免强引用循环时。例如:
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:
A类< - > B类
Class A <-> Class B
A类的init例程需要创建(和B类,B需要弱引用回A:
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
}
}
现在,
- B类需要引用A类进行初始化。
- A类只有在完全初始化后才能将
self
传递给B类的初始化。 - 为了在创建B类之前将A类视为初始化,因此属性
instanceOfB
必须是可选的。
- 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.
然而,一旦创建了A,使用instanceOfB访问instanceOfB会很烦人!因为我们知道必须有一个B
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
为了避免这种情况,将instanceOfB声明为implicity unwrapped optional(instanceOfB!),并且我们可以使用instanceOfB来访问它。 (此外,我怀疑编译器也可以不同地优化访问)。
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).
这方面的一个例子见第464至466页这本书。
An example of this is given on pages 464 to 466 of the book.
- 使用?如果将来该值变为零,那么您可以对此进行测试。
- 使用!如果它真的不应该在未来变为零,但最初需要为零。
这篇关于String之间有什么区别?和字符串! (创建可选变量的两种方法)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!