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”,因为我最初的想法。我只是误解了《人与人》是完全不同的类型。一旦我明白了,所有其他的?,!疯狂,以及下面这些精彩的回答,让我觉得更有道理。


当前回答

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

从文档

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

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

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

其他回答

下面是一些例子:

var name:String = "Hello World"
var word:String?

其中word是可选值。意味着它可能包含或不包含某个值。

word = name 

这里name有一个值,所以我们可以给它赋值

var cow:String = nil
var dog:String!

狗被强制打开意味着它必须包含一个值

dog = cow

应用程序将崩溃,因为我们将nil赋值给unwrapped

John是一个可选的Person,这意味着它可以保存值或为nil。

john.apartment = number73

如果John不是可选选项,则使用。由于john从不为nil,我们可以确定它不会在nil值时调用apartment。而

john!.apartment = number73

向编译器承诺John不是nil,然后打开可选选项以获取John的值并访问John的公寓属性。如果你知道john不是nil就用这个。如果你在可选的nil上调用这个,你会得到一个运行时错误。

文档中包含了一个很好的示例,其中convertedNumber是可选的。

if convertedNumber {
    println("\(possibleNumber) has an integer value of \(convertedNumber!)")
} else {
    println("\(possibleNumber) could not be converted to an integer")
}

简单地说

USING感叹号表示变量必须包含非nil值(它永远不会是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

 {..}

问问你自己

这种类型的人吗?有公寓会员/房产?或 这种类型的人有公寓成员/房产吗?

如果你不能回答这个问题,那么继续阅读:

要理解,你可能需要对泛型有超基础的理解。在这里看到的。Swift中的很多东西都是用泛型编写的。可选的包括

下面的代码可以从斯坦福大学的视频中获得。强烈推荐你看前5分钟

“Optional”为enum,只有2个大小写

enum Optional<T>{
    case None
    case Some(T)
}

let x: String? = nil //actually means:

let x = Optional<String>.None

let x :String? = "hello" //actually means:

let x = Optional<String>.Some("hello")

var y = x! // actually means:

switch x {
case .Some(let value): y = value
case .None: // Raise an exception
}

可选的绑定:

let x:String? = something
if let y = x {
    // do something with y
}
//Actually means:

switch x{
case .Some(let y): print)(y) // or whatever else you like using 
case .None: break
}

当你说var的时候john: Person?你的意思是:

enum Optional<Person>{
case .None
case .Some(Person)
}

上面的枚举是否有名为apartment的属性?你看到它了吗?根本就不在那儿!然而,如果你打开它ie做人!然后你就可以……它在引擎盖下面做的是:Optional<Person>。一些(人(名字:“John Appleseed”))


你是否定义了var john: Person而不是:var john: Person?那么你就不再需要了!使用,因为Person本身有一个apartment的成员


作为以后讨论为什么使用!打开包装有时不建议看这个问答