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


当前回答

问问你自己

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

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

要理解,你可能需要对泛型有超基础的理解。在这里看到的。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的成员


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

其他回答

问问你自己

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

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

要理解,你可能需要对泛型有超基础的理解。在这里看到的。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的成员


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

如果你来自c语言家族,你会想“指向X类型对象的指针,它可能是内存地址0 (NULL)”,如果你来自动态类型语言,你会想“对象可能是X类型,但可能是未定义的类型”。这两种说法实际上都不正确,尽管迂回地说,第一个说法很接近。

你应该把它想象成一个物体:

struct Optional<T> {
   var isNil:Boolean
   var realObject:T
}

When you're testing your optional value with foo == nil it's really returning foo.isNil, and when you say foo! it's returning foo.realObject with an assertion that foo.isNil == false. It's important to note this because if foo actually is nil when you do foo!, that's a runtime error, so typically you'd want to use a conditional let instead unless you are very sure that the value will not be nil. This kind of trickery means that the language can be strongly typed without forcing you to test if values are nil everywhere.

实际上,它并不是这样做的,因为工作是由编译器完成的。在高层次上有一个类型Foo?它与Foo是分开的,这可以防止接受类型Foo的函数函数接收到nil值,但在低级别上,可选值不是一个true对象,因为它没有属性或方法;实际上,它很可能是一个指针,在强制展开时,通过适当的测试,它可能是NULL(0)。

还有一种情况,你会看到感叹号是在一种类型上,比如:

func foo(bar: String!) {
    print(bar)
}

这大致相当于接受一个强制展开的可选选项,即:

func foo(bar: String?) {
    print(bar!)
}

你可以使用它来创建一个方法,该方法在技术上接受一个可选值,但如果它为nil,则会出现运行时错误。在当前版本的Swift中,这显然绕过了is-not-nil断言,所以你会有一个低级错误。通常不是个好主意,但在从另一种语言转换代码时可能很有用。

博士TL;

感叹号在Swift语言中是什么意思?

感叹号实际上是在说:“我知道这是可选的 肯定有一个值;请使用它。”这被称为可选值的强制展开:

例子

let possibleString: String? = "An optional string."
print(possibleString!) // requires an exclamation mark to access its value
// prints "An optional string."

let assumedString: String! = "An implicitly unwrapped optional string."
print(assumedString)  // no exclamation mark is needed to access its value
// prints "An implicitly unwrapped optional string."

来源:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html / / apple_ref / doc / uid / TP40014097-CH5-XID_399

简单地说

USING感叹号表示变量必须包含非nil值(它永远不会是nil)

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

myVar:字符串?= "东西"

myVar:字符串?= nil

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

在情况2中,它会崩溃。

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