String之间有什么区别?和字符串!(创建可选变量的两种方法)?

h0u*_*sni 53 ios swift

Swift编程语言(Apple的书)中,我读过您可以通过两种方式创建可选变量:使用问号(?)或使用感叹号(!).

区别在于,当您使用(?)获取可选值时,每次需要值时都必须使用感叹号:

var str: String? = "Question mark?"
println(str!) // Exclamation mark needed
str = nil    
Run Code Online (Sandbox Code Playgroud)

使用(!)时,您可以在没有后缀的情况下获取它:

var str: String! = "Exclamation mark!"
println(str) // No suffix needed
str = nil
Run Code Online (Sandbox Code Playgroud)

有什么区别,如果没有任何区别,为什么有2种方法?

tar*_*mes 60

使用隐式展开的选项(使用!声明)的真正好处与类初始化有关,当两个类指向彼此并且您需要避免强引用循环时.例如:

A类< - > B类

A类的init例程需要创建(并拥有)B类,B需要弱引用回A:

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

class B {
    unowned let instanceOfA: A
    init(instanceOfA: A) {
        self.instanceOfA = instanceOfA
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,

  • B类需要引用A类进行初始化.
  • A类只有self在完全初始化后才能传递给B类的初始化.
  • 为了在创建B类之前将A类视为初始化,instanceOfB因此该属性必须是可选的.

但是,一旦创建了A,使用instanceOfB访问instanceOfB会很烦人!因为我们知道必须有B

为了避免这种情况,instanceOfB被声明为implicity unwrapped可选(instanceOfB!),我们可以使用instanceOfB来访问它.(此外,我怀疑编译器也可以不同地优化访问).

这方面的一个例子在本书的第464至466页给出.

摘要:

  • 使用 ?如果将来该值变为零,那么您需要对此进行测试.
  • 使用 !如果它真的不应该在未来变为零,但它最初需要为零.

  • 最后一个答案真的回答了我的问题,而不是简单地背诵书,+ 1 (4认同)
  • @Whome instanceOfA不是关键字,它是我给出的参数名称.默认情况下,所有初始化程序都具有必须使用的外部参数名称,因此除非您使用_作为外部参数名称声明B的init函数,否则不能执行B(self).init(_ instanceOfA:A). (2认同)

Ana*_*ile 7

你应该超越语法糖.

有两种完全不同的多态类型.语法糖只使用这些类型中的一种或另一种.

当你写作Foo?你真正拥有的类型Optional<Foo>时,当你写作时Foo!你真的有ImplicitlyUnwrappedOptional<Foo>.

这是两种不同的类型,它们也有所不同Foo.