Swift编程语言指南中有如下示例:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { println("\(name) is being deinitialized") }
}

class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    var tenant: Person?
    deinit { println("Apartment #\(number) is being deinitialized") }
}

var john: Person?
var number73: Apartment?

john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)

//From Apple's “The Swift Programming Language” guide (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html)

然后,在给这个人分配公寓时,他们使用感叹号来“打开实例”:

john!.apartment = number73

“展开实例”是什么意思?为什么有必要?它与仅仅做以下事情有什么不同:

john.apartment = number73

我对Swift语言很不熟悉。我只是想把基本的东西记下来。

更新: 我遗漏了一个很大的谜团(答案中没有直接说明——至少在写这篇文章的时候没有),那就是当你做以下事情的时候:

var john: Person?

这并不意味着“约翰是人的类型,它可能是nil”,因为我最初的想法。我只是误解了《人与人》是完全不同的类型。一旦我明白了,所有其他的?,!疯狂,以及下面这些精彩的回答,让我觉得更有道理。


当前回答

在objective C中,没有值的变量等于“nil”(也可以使用与0和false相同的“nil”值),因此可以在条件语句中使用变量(有值的变量与“TRUE”相同,而那些没有值的变量等于“false”)。

Swift通过提供“可选值”来提供类型安全。即,它可以防止因分配不同类型的变量而形成错误。

所以在Swift中,只有条件语句可以提供布尔值。

var hw = "Hello World"

这里,虽然'hw'是一个字符串,但它不能像objective - C那样在if语句中使用。

//This is an error

if hw

 {..}

为此,它需要被创建为,

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}

其他回答

!在对象的末尾表示该对象是可选的,如果它可以返回nil则展开。这通常用于捕获错误,否则会使程序崩溃。

The entire story begins with a feature of swift called optional vars. These are the vars which may have a value or may not have a value. In general swift doesn't allow us to use a variable which isn't initialised, as this may lead to crashes or unexpected reasons and also server a placeholder for backdoors. Thus in order to declare a variable whose value isn't initially determined we use a '?'. When such a variable is declared, to use it as a part of some expression one has to unwrap them before use, unwrapping is an operation through which value of a variable is discovered this applies to objects. Without unwrapping if you try to use them you will have compile time error. To unwrap a variable which is an optional var, exclamation mark "!" is used.

有时候你知道这样的可选变量会被系统或者你自己的程序赋值,但是稍后,比如UI outlet,在这种情况下,我们不会用问号"?"来声明可选变量,而是用"!"

因此,系统知道这个用“!”声明的变量现在是可选的,没有值,但将在其生命周期的后期接收一个值。

因此,感叹号有两种不同的用法, 1. 声明一个变量,该变量将是可选的,并且以后一定会接收值 2. 在表达式中使用可选变量之前,将其展开。

以上描述避免了太多的技术问题,我希望。

可选变量可以包含值,也可以不包含值

myVar:字符串?= "东西"

myVar:字符串?= nil

现在如果你问myVar!,你告诉编译器返回一个值在情况1中它会返回"Something"

在情况2中,它会崩溃。

的意思!Mark将强制编译器返回一个值,即使它不存在。这就是为什么这个名字叫Force unwrapped。

John是一个可选的变量,它可以包含一个nil值。要确保该值不是nil,请使用a !在var名称的末尾。

从文档

一旦您确定可选选项确实包含一个值,您可以通过在可选选项名称的末尾添加一个感叹号(!)来访问它的底层值。感叹号有效地表示,“我知道这个可选选项肯定有价值;请使用它。”

另一种检查非nil值的方法是(可选的展开)

    if let j = json {
        // do something with j
    }

如果john是一个可选的变量(这样声明)

var john: Person?

那么john可能没有值(在ObjC中为nil值)

感叹号基本上告诉编译器“我知道这有一个值,你不需要测试它”。如果你不想使用它,你可以有条件地测试它:

if let otherPerson = john {
    otherPerson.apartment = number73
}

只有当john有值时,这个内部才有价值。