ChatGPT解决这个技术问题 Extra ChatGPT

Swift 中的可选值是什么?

Apple's documentation

您可以使用 if 和 let 一起处理可能丢失的值。这些值表示为可选项。可选值要么包含一个值,要么包含 nil 以指示缺少该值。在值的类型后写一个问号 (?) 以将该值标记为可选。

为什么要使用可选值?

Optional 也可以被视为 Option / Maybe monad 的实现。这个 blog here 很好地解释了一个难以理解的概念。
tldr:“Swift 需要你清楚什么时候可以丢失一个值,什么时候可以保证它存在。”来自 nevan king 的excellent answer below

C
Community

Swift 中的 optional 是一种可以保存值或不保存值的类型。可选项是通过将 ? 附加到任何类型来编写的:

var name: String? = "Bertie"

可选项(连同泛型)是最难理解的 Swift 概念之一。由于它们的编写和使用方式,很容易对它们是什么产生错误的认识。将上面的可选项与创建普通字符串进行比较:

var name: String = "Bertie" // No "?" after String

从语法上看,可选字符串与普通字符串非常相似。它不是。可选字符串不是打开了某些“可选”设置的字符串。它不是一种特殊的字符串。 String 和可选 String 是完全不同的类型。

最重要的是要知道:可选项是一种容器。可选字符串是可能包含字符串的容器。可选的 Int 是可能包含 Int 的容器。将可选项视为一种包裹。在您打开它(或用可选语言“解包”)之前,您将不知道它是否包含某些内容。

您可以在 Swift 标准库中看到 how optionals are implemented,方法是在任何 Swift 文件中键入“可选”并 ⌘-单击它。这是定义的重要部分:

enum Optional<Wrapped> {
    case none
    case some(Wrapped)
}

Optional 只是一个 enum,它可以是以下两种情况之一:.none.some。如果它是 .some,则有一个关联值,在上面的示例中,它将是 String“Hello”。可选项使用泛型为关联值提供类型。可选字符串的类型不是 String,而是 Optional,或更准确地说是 Optional<String>

Swift 对可选项所做的一切都是让阅读和编写代码更加流畅的魔法。不幸的是,这掩盖了它实际工作的方式。稍后我将介绍一些技巧。

注意:我会经常谈论可选变量,但也可以创建可选常量。我用它们的类型标记所有变量,以便更容易理解正在创建的类型类型,但您不必在自己的代码中。

如何创建选项

要创建可选项,请在要包装的类型后附加 ?。任何类型都可以是可选的,甚至是您自己的自定义类型。类型和 ? 之间不能有空格。

var name: String? = "Bob" // Create an optional String that contains "Bob"
var peter: Person? = Person() // An optional "Person" (custom type)

// A class with a String and an optional String property
class Car {
var modelName: String // must exist
var internalName: String? // may or may not exist
}

使用选项

您可以将可选项与 nil 进行比较以查看它是否具有值:

var name: String? = "Bob"
name = nil // Set name to nil, the absence of a value
if name != nil {
    print("There is a name")
}
if name == nil { // Could also use an "else"
    print("Name has no value")
}

这有点令人困惑。这意味着可选是一件事或另一件事。它要么是 nil,要么是“Bob”。这不是真的,可选项不会转换成别的东西。将其与 nil 进行比较是一种使代码更易于阅读的技巧。如果可选项等于 nil,这仅表示枚举当前设置为 .none

只有可选项可以为 nil

如果您尝试将非可选变量设置为 nil,则会出现错误。

var red: String = "Red"
red = nil // error: nil cannot be assigned to type 'String'

另一种看待可选项的方式是作为普通 Swift 变量的补充。它们是保证有值的变量的对应物。 Swift 是一种谨慎的语言,它讨厌歧义。大多数变量都被定义为非可选变量,但有时这是不可能的。例如,想象一个视图控制器从缓存或网络加载图像。在创建视图控制器时,它可能有也可能没有该图像。无法保证 image 变量的值。在这种情况下,您必须将其设为可选。它以 nil 开头,当检索到图像时,可选值会得到一个值。

使用可选项揭示了程序员的意图。与任何对象都可以为 nil 的 Objective-C 相比,Swift 需要你清楚什么时候可以丢失一个值,什么时候可以保证它存在。

要使用一个可选的,你“解包”它

不能使用可选的 String 代替实际的 String。要在可选项中使用包装的值,您必须将其解包。解开可选项的最简单方法是在可选项名称后添加 !。这称为“强制展开”。它返回可选项内的值(作为原始类型),但如果可选项是 nil,则会导致运行时崩溃。在打开包装之前,您应该确保有一个值。

var name: String? = "Bob"
let unwrappedName: String = name!
print("Unwrapped name: \(unwrappedName)")

name = nil
let nilName: String = name! // Runtime crash. Unexpected nil.

检查和使用可选

因为在展开和使用可选项之前,您应该始终检查 nil,这是一种常见的模式:

var mealPreference: String? = "Vegetarian"
if mealPreference != nil {
    let unwrappedMealPreference: String = mealPreference!
    print("Meal: \(unwrappedMealPreference)") // or do something useful
}

在此模式中,您检查一个值是否存在,然后当您确定它存在时,您将其强制解包为一个临时常量以供使用。因为这是很常见的事情,Swift 提供了一个使用“if let”的快捷方式。这称为“可选绑定”。

var mealPreference: String? = "Vegetarian"
if let unwrappedMealPreference: String = mealPreference {
    print("Meal: \(unwrappedMealPreference)") 
}

这将创建一个临时常量(如果将 let 替换为 var,则为变量),其范围仅在 if 的大括号内。因为必须使用像“unwrappedMealPreference”或“realMealPreference”这样的名称是一种负担,Swift 允许您重用原始变量名称,在括号范围内创建一个临时名称

var mealPreference: String? = "Vegetarian"
if let mealPreference: String = mealPreference {
    print("Meal: \(mealPreference)") // separate from the other mealPreference
}

下面是一些代码来演示使用了不同的变量:

var mealPreference: String? = "Vegetarian"
if var mealPreference: String = mealPreference {
    print("Meal: \(mealPreference)") // mealPreference is a String, not a String?
    mealPreference = "Beef" // No effect on original
}
// This is the original mealPreference
print("Meal: \(mealPreference)") // Prints "Meal: Optional("Vegetarian")"

可选绑定通过检查可选是否等于 nil 来工作。如果没有,它会将可选项解包到提供的常量中并执行块。在 Xcode 8.3 及更高版本 (Swift 3.1) 中,尝试打印像这样的可选项将导致无用的警告。使用可选的 debugDescription 使其静音:

print("\(mealPreference.debugDescription)")

什么是可选的?

选项有两个用例:

可能失败的事情(我期待某事,但我什么都没有) 现在什么都不是但以后可能会发生的事情(反之亦然)

一些具体的例子:

可以存在或不存在的属性,例如 Person 类中的 middleName 或配偶

可以返回值或不返回任何值的方法,例如在数组中搜索匹配项

一种可以返回结果或得到错误且不返回任何内容的方法,例如尝试读取文件的内容(通常返回文件的数据)但文件不存在

委托属性,不一定要设置,一般在初始化后设置

对于类中的弱属性。他们指向的东西可以随时设置为零

可能必须释放以回收内存的大型资源

当您需要一种方法来知道何时设置了值(数据尚未加载>数据)而不是使用单独的 dataLoaded Boolean

Objective-C 中不存在可选项,但有一个等效的概念,返回 nil。可以返回对象的方法可以返回 nil。这被认为意味着“没有有效的对象”,并且通常用来表示出现了问题。它仅适用于 Objective-C 对象,不适用于原语或基本 C 类型(枚举、结构)。 Objective-C 通常有专门的类型来表示这些值的缺失(NSNotFound 实际上是 NSIntegerMaxkCLLocationCoordinate2DInvalid 表示无效坐标,-1 或一些负值也被使用)。编码人员必须了解这些特殊值,因此必须针对每种情况记录和学习它们。如果方法不能将 nil 作为参数,则必须记录在案。在 Objective-C 中,nil 是一个指针,就像所有对象都被定义为指针一样,但 nil 指向一个特定的(零)地址。在 Swift 中,nil 是一个字面量,表示没有某种类型。

与零相比

您过去可以使用任何可选作为 Boolean

let leatherTrim: CarExtras? = nil
if leatherTrim {
    price = price + 1000
}

在更新的 Swift 版本中,您必须使用 leatherTrim != nil。为什么是这样?问题是 Boolean 可以包含在可选中。如果您有这样的 Boolean

var ambiguous: Boolean? = false

它有两种“假”,一种没有值,一种有值但值为false。 Swift 讨厌模棱两可,所以现在您必须始终检查 nil 的可选项。

您可能想知道可选的 Boolean 有什么意义?与其他可选项一样,.none 状态可能表明该值是未知的。网络调用的另一端可能有一些东西需要一些时间来轮询。可选布尔值也称为“Three-Value Booleans

快速技巧

Swift 使用一些技巧来允许选项工作。考虑这三行普通的可选代码;

var religiousAffiliation: String? = "Rastafarian"
religiousAffiliation = nil
if religiousAffiliation != nil { ... }

这些行都不应该编译。

第一行使用字符串文字设置一个可选字符串,两种不同的类型。即使这是一个字符串,类型也不同

第二行设置一个可选的String为nil,两种不同的类型

第三行将一个可选字符串与 nil 进行比较,两种不同的类型

我将介绍一些允许这些行工作的选项的实现细节。

创建一个可选的

使用 ? 创建可选的是语法糖,由 Swift 编译器启用。如果你想长期这样做,你可以创建一个这样的可选:

var name: Optional<String> = Optional("Bob")

这将调用 Optional 的第一个初始化程序 public init(_ some: Wrapped),它从括号中使用的类型推断出可选的关联类型。

创建和设置可选的更长的方法:

var serialNumber:String? = Optional.none
serialNumber = Optional.some("1234")
print("\(serialNumber.debugDescription)")

将可选项设置为 nil

您可以创建一个没有初始值的可选,或者创建一个初始值为 nil 的可选(两者具有相同的结果)。

var name: String?
var name: String? = nil

允许选项等于 nil 由协议 ExpressibleByNilLiteral(以前称为 NilLiteralConvertible)启用。可选项是使用 Optional 的第二个初始化程序 public init(nilLiteral: ()) 创建的。文档说您不应该将 ExpressibleByNilLiteral 用于除可选项之外的任何内容,因为这会改变代码中 nil 的含义,但可以这样做:

class Clint: ExpressibleByNilLiteral {
    var name: String?
    required init(nilLiteral: ()) {
        name = "The Man with No Name"
    }
}

let clint: Clint = nil // Would normally give an error
print("\(clint.name)")

相同的协议允许您将已创建的可选项设置为 nil。虽然不推荐,但您可以直接使用 nil 文字初始化器:

var name: Optional<String> = Optional(nilLiteral: ())

将可选项与 nil 进行比较

选项定义了两个特殊的“==”和“!=”运算符,您可以在 Optional 定义中看到它们。第一个 == 允许您检查是否有任何可选项等于 nil。如果关联的类型相同,则设置为 .none 的两个不同的选项将始终相等。当你与 nil 进行比较时,Swift 在幕后创建了一个相同关联类型的可选项,设置为 .none 然后使用它进行比较。

// How Swift actually compares to nil
var tuxedoRequired: String? = nil
let temp: Optional<String> = Optional.none
if tuxedoRequired == temp { // equivalent to if tuxedoRequired == nil
    print("tuxedoRequired is nil")
}

第二个 == 运算符允许您比较两个选项。两者必须是相同的类型,并且该类型需要符合 Equatable(允许将事物与常规“==”运算符进行比较的协议)。 Swift(大概)解开这两个值并直接比较它们。它还处理其中一个或两个选项都是 .none 的情况。请注意与 nil 文字比较之间的区别。

此外,它允许您将任何 Equatable 类型与该类型的可选包装进行比较:

let numberToFind: Int = 23
let numberFromString: Int? = Int("23") // Optional(23)
if numberToFind == numberFromString {
    print("It's a match!") // Prints "It's a match!"
}

在幕后,Swift 在比较之前将非可选包装为可选。它也适用于文字 (if 23 == numberFromString {)

我说有两个 == 运算符,但实际上还有第三个运算符允许您将 nil 放在比较的左侧

if nil == name { ... }

命名选项

没有 Swift 约定来命名可选类型与非可选类型不同。人们避免在名称中添加一些内容以表明它是可选的(如“optionalMiddleName”或“possibleNumberAsString”),并让声明显示它是可选类型。当你想命名一些东西来保存可选的值时,这会变得很困难。 “middleName”这个名字意味着它是一个字符串类型,所以当你从中提取字符串值时,你通常会得到像“actualMiddleName”或“unwrappedMiddleName”或“realMiddleName”这样的名称。使用可选绑定并重用变量名来解决这个问题。

官方定义

"The Basics" in the Swift Programming Language

Swift 还引入了可选类型,用于处理值的缺失。可选项要么说“有一个值,它等于 x”,要么说“根本没有一个值”。可选项类似于在 Objective-C 中使用带指针的 nil,但它们适用于任何类型,而不仅仅是类。 Optional 比 Objective-C 中的 nil 指针更安全、更具表现力,并且是 Swift 许多最强大功能的核心。可选项是 Swift 是一种类型安全语言这一事实的一个例子。 Swift 帮助你清楚你的代码可以使用的值的类型。如果您的部分代码需要一个字符串,类型安全会阻止您错误地传递一个 Int。这使您能够在开发过程中尽早发现并修复错误。

最后,这是一首 1899 年关于可选的诗:

昨天在楼梯上
我遇到了一个不在那里的人
他今天又不在了
我希望,我希望他离开

{ 1}

更多资源:

Swift 编程指南

Swift 中的可选项(中)

WWDC Session 402 “Swift 简介”(大约 14:15 开始)

更多可选提示和技巧


@KaanDedeoglu 不幸的是,史蒂夫在很大程度上是可选的。他在这里,现在他不在。
if myString 不再编译。您需要 if myString != nil。请参阅documentation
最好和最清楚的解释?和 !在网上找到的 Swift 中使用。谢谢你
mateo 深入解释了 Optionals,深入浅出和简单的示例。
感谢您的解释,它比Apple自己的文档清晰得多。
J
John Riselvato

让我们以 NSError 为例,如果没有返回错误,您希望将其设为可选以返回 Nil。如果没有错误,给它赋值是没有意义的..

var error: NSError? = nil

这也允许你有一个默认值。因此,如果函数未传递任何内容,您可以将方法设置为默认值

func doesntEnterNumber(x: Int? = 5) -> Bool {
    if (x == 5){
        return true
    } else {
        return false
    }
}

“如果它是 nil,任何带有它的表达式的结果也是 nil”这句话是完全错误的。即使表达式中有一个可选值 nilfunc isNil<T>(t: T?) -> Bool { return t == nil } 也会返回 true
非常糟糕的代码示例。你就不能想点更好的吗?为什么不简单地return x == 5? 5有什么特别之处?
不,两年前我想不出更好的东西。今天是的,但这是否说明问题?是的。感谢@Atomosk 的输入,它真的很有帮助。
r
rickster

在 Swift 中你不能有一个指向 nil 的变量——没有指针,也没有空指针。但是在 API 中,您通常希望能够指示特定类型的值或缺少值 - 例如,我的窗口是否有委托,如果有,它是谁? Optional 是 Swift 的类型安全、内存安全的方法。


T
Teodor Ciuraru

我做了一个简短的回答,总结了上述大部分内容,以消除我作为初学者的不确定性:

与Objective-C相反,Swift中没有变量可以包含nil,所以增加了Optional变量类型(变量后缀“?”):

    var aString = nil //error

最大的区别是 Optional 变量不直接存储值(就像普通的 Obj-C 变量那样)它们包含两种状态:“有值”或“没有值”:

    var aString: String? = "Hello, World!"
    aString = nil //correct, now it contains the state "has nil"

也就是说,您可以在不同的情况下检查这些变量:

if let myString = aString? {
     println(myString)
}
else { 
     println("It's nil") // this will print in our case
}

通过使用“!”后缀,您还可以访问包装在其中的值,前提是这些值存在。 (即它不是零):

let aString: String? = "Hello, World!"
// var anotherString: String = aString //error
var anotherString: String = aString!

println(anotherString) //it will print "Hello, World!"

这就是为什么你需要使用“?”和 ”!”并且默认情况下不使用所有这些。 (这是我最大的困惑)

我也同意上面的答案:可选类型不能用作布尔值。


G
Gokul

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

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

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

var hw = "Hello World"

在这里,即使 'hw' 是一个字符串,它也不能像在目标 C 中那样在 if 语句中使用。

//This is an error

if hw

 {..}

为此,它需要创建为,

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}

M
Maria Zverina

可选值允许您显示缺少值。有点像 SQL 中的 NULL 或 Objective-C 中的 NSNull。我想这将是一个改进,因为您甚至可以将其用于“原始”类型。

// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)”

摘自:Apple Inc.“Swift 编程语言”。电子书。 https://itun.es/gb/jEUH0.l


nil 只是枚举常量 OptionalValue<T>.None 的语法糖(其中 T 是适合您使用 nil 的上下文的类型)。 ?OptionalValue<T>.Some(T) 的快捷方式。
G
GJZ

可选意味着 Swift 不完全确定该值是否对应于类型:例如,Int?意味着 Swift 并不完全确定该数字是否为 Int。

要删除它,您可以使用三种方法。

1)如果您完全确定类型,您可以使用感叹号强制解包,如下所示:

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

如果你强制解开一个可选项并且它等于 nil,你可能会遇到这个崩溃错误:

https://i.stack.imgur.com/DmJJn.png

这不一定安全,所以如果您不确定类型和值,这里有一个方法可以防止崩溃:

方法二和三可以防范这个问题。

2)隐式展开的可选

 if let unwrappedAge = age {

 // continue in here

 }

请注意,展开的类型现在是 Int,而不是 Int?。

3) 守卫声明

 guard let unwrappedAge = age else { 
   // continue in here
 }

从这里,您可以继续使用未包装的变量。如果您确定变量的类型,请确保仅强制展开(使用!)。

祝你的项目好运!


A
Asme Just

当我开始学习 Swift 时,很难理解为什么是可选的

让我们这样想。让我们考虑一个类 Person,它有两个属性 namecompany

class Person: NSObject {
    
    var name : String //Person must have a value so its no marked as optional
    var companyName : String? ///Company is optional as a person can be unemployed that is nil value is possible
    
    init(name:String,company:String?) {
        
        self.name = name
        self.companyName = company
        
    }
}

现在让我们创建几个 Person 的对象

var tom:Person = Person.init(name: "Tom", company: "Apple")//posible
var bob:Person = Person.init(name: "Bob", company:nil) // also Possible because company is marked as optional so we can give Nil

但是我们不能将 Nil 传递给 name

var personWithNoName:Person = Person.init(name: nil, company: nil)

现在让我们谈谈我们为什么使用 optional?。让我们考虑一种情况,我们希望在公司名称之后添加 Inc,例如 apple 将是 apple Inc。我们需要在公司名称后附加 Inc 并打印。

print(tom.companyName+" Inc") ///Error saying optional is not unwrapped.
print(tom.companyName!+" Inc") ///Error Gone..we have forcefully unwrap it which is wrong approach..Will look in Next line
print(bob.companyName!+" Inc") ///Crash!!!because bob has no company and nil can be unwrapped.

现在让我们研究一下为什么 optional 会发生。

if let companyString:String = bob.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
    
    print(companyString+" Inc") //Will never executed and no crash!!!
}

让我们将 bob 替换为 tom

if let companyString:String = tom.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
    
    print(companyString+" Inc") //Will executed and no crash!!!
}

恭喜!我们已经妥善处理了optional?

所以实现点是

如果变量可能为 nil,我们会将其标记为可选如果我们想在代码中的某个地方使用此变量,编译器会提醒您,如果该变量包含 nil,我们需要检查我们是否正确处理了该变量。

谢谢...快乐编码


T
Tunvir Rahman Tusher

让我们用下面的代码 Playground 进行实验。我希望能清楚地知道什么是可选的以及使用它的原因。

var sampleString: String? ///Optional, Possible to be nil

sampleString = nil ////perfactly valid as its optional

sampleString = "some value"  //Will hold the value

if let value = sampleString{ /// the sampleString is placed into value with auto force upwraped.

    print(value+value)  ////Sample String merged into Two
}

sampleString = nil // value is nil and the

if let value = sampleString{

    print(value + value)  ///Will Not execute and safe for nil checking
}

//   print(sampleString! + sampleString!)  //this line Will crash as + operator can not add nil

P
Pang

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html

可选链是查询和调用当前可能为 nil 的可选的属性、方法和下标的过程。如果可选包含值,则属性、方法或下标调用成功;如果可选项为 nil,则属性、方法或下标调用返回 nil。多个查询可以链接在一起,如果链中的任何链接为零,则整个链都会优雅地失败。

要更深入地了解,请阅读上面的链接。


K
Krunal

出色地...

(可选)表示您的变量可能包含 nil 值,而 ! (unwrapper) 表示您的变量在运行时使用(试图从中获取值)时必须具有内存(或值)。

主要区别在于,当可选项为 nil 时,可选项链接会优雅地失败,而当可选项为 nil 时,强制解包会触发运行时错误。

为了反映可以对 nil 值调用可选链接这一事实,可选链接调用的结果始终是可选值,即使您正在查询的属性、方法或下标返回非可选值也是如此。您可以使用此可选返回值来检查可选链接调用是否成功(返回的可选包含一个值),或者由于链中的 nil 值而没有成功(返回的可选值为 nil)。

具体来说,可选链接调用的结果与预期返回值的类型相同,但包装在可选中。通常返回 Int 的属性将返回 Int?通过可选链接访问时。

var defaultNil : Int?  // declared variable with default nil value
println(defaultNil) >> nil  

var canBeNil : Int? = 4
println(canBeNil) >> optional(4)

canBeNil = nil
println(canBeNil) >> nil

println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper

var canNotBeNil : Int! = 4
print(canNotBeNil) >> 4

var cantBeNil : Int = 4
cantBeNil = nil // can't do this as it's not optional and show a compile time error

这是 Apple 开发者委员会提供的详细基本教程:Optional Chaining


V
Vicky Prajapati

Swift 中的 optional 是一种可以保存值或不保存值的类型。可选项是通过附加一个 ?任何类型:

var name: String?

您可以参考此链接深入了解:https://medium.com/@agoiabeladeyemi/optionals-in-swift-2b141f12f870


N
Nathan Day

有很多错误是由人们试图使用未设置的值引起的,有时这可能会导致崩溃,在目标 c 中试图调用 nil 对象引用的方法将被忽略,所以你的一些代码未执行,编译器或编写的代码无法告诉您原因。一个可选参数让您拥有永远不会为零的变量,如果您尝试构建它,编译器可以在您的代码甚至有机会运行之前告诉您,或者您可以决定它适合未定义的对象,然后编译器会在您尝试编写未考虑到这一点的内容时告诉您。

在调用一个可能的 nil 对象的情况下,你可以去

object?.doSomthing()

你已经向编译器和任何阅读你的代码的人明确表示,它的可能对象是 nil 并且什么都不会发生。有时你有几行代码你只想在值存在时出现,所以你可以这样做

if let obj = object {
    obj.doSomthing()
    doSomethingto(obj)
}

这两个语句仅在对象是某物时才会执行,同样,如果它不是某物,您可能希望停止整个代码块的其余部分

guard let obj = object {
    return
}
obj.doSomthing()
doSomethingto(obj)

如果之后的所有内容仅在对象是某物时才适用,则阅读起来会更简单,另一种可能是您想使用默认值

let obj = object ?? <default-object>
obj.doSomthing()
doSomethingto(obj)

现在 obj 将被分配给某些东西,即使它是该类型的默认值

选项在以下情况下很有用它对它做任何事情直到它被设置,我喜欢使用选项的一种方法是告诉我必须做一些事情,或者例如是否已经完成

func eventFired() {
    guard timer == nil else { return }
    timer = scheduleTimerToCall(method, in: 60)
}

func method() {
    doSomthing()
    timer = nil
}

此 sudo 代码可以多次调用 eventFired,但只有在第一次调用时才会安排计时器,一旦安排执行,它就会运行一些方法并将计时器设置回 nil,以便可以安排另一个计时器。

一旦您绕过处于未定义状态的变量,您就可以将其用于所有类型的事情。


m
maazza

这是 Swift 中一个等效的可选声明:

var middleName: String?

该声明创建了一个名为 middleName 的 String 类型的变量。 String 变量类型后面的问号 (?) 表示 middleName 变量可以包含一个可以是 String 或 nil 的值。任何查看此代码的人都会立即知道 middleName 可以为 nil。这是自我记录!

如果您没有为可选的常量或变量指定初始值(如上所示),则该值会自动为您设置为 nil。如果您愿意,可以将初始值显式设置为 nil:

var middleName: String? = nil

有关可选的更多详细信息,请阅读以下链接

http://www.iphonelife.com/blog/31369/swift-101-working-swifts-new-optional-values


使用这个, var middleName: String! = ""