字符串有什么区别?和字符串!(创建可选变量的两种方法)? [英] What is the difference between String? and String! (two ways of creating an optional variable)?
问题描述
在 The Swift Programming Language(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
有什么区别,如果完全没有区别,为什么会有两种方法?
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 类的初始化例程需要创建(并拥有)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 类的初始化程序. - 为了使类 A 在创建类 B 之前被视为已初始化,因此属性
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 被声明为一个隐式解包可选(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.
- 使用?如果该值将来可以变为 nil,那么您可以对此进行测试.
- 使用!如果将来真的不应该变为nil,但最初需要变为nil.
这篇关于字符串有什么区别?和字符串!(创建可选变量的两种方法)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!