字符串有什么区别?和字符串!(创建可选变量的两种方法)? [英] What is the difference between String? and String! (two ways of creating an optional variable)?

查看:27
本文介绍了字符串有什么区别?和字符串!(创建可选变量的两种方法)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆