Swift 4 Introduction系列1.6 — Swift数据类型可选

Optionals是一个后缀运算符,可以附加到任何数据类型。 可选项目以问号( )表示。 我们使用可选参数来指示变量所分配给的数据类型可以不包含任何值。 我们使用关键字( nil )分配一个没有值的可选内容。 只有声明为可选变量的变量才能分配nil值。

我们在某些情况下声明了可选变量,在这种情况下我们不知道输入源是否包含数据。 可选选项使程序更安全地进行编码。

例如,声明为( Int? )的变量; 告诉系统该变量可能没有任何值。 我们可以测试变量是否有值,如果有值,可以从变量中解包值。

用于指示或声明可选选项的语法如下:

例如,要声明一个可选变量,我们执行以下操作:

  var someOptional1:Int? 
var someOptional2:String?
var someOptional3:Double?
var someOptional4:Bool?someOptional1
someOptional2
someOptional3
someOptional4

请注意,在声明可选变量时,我们不需要初始化变量,因为可选变量数据类型变量会自动初始化为无值或nil。 但是, 自动初始化仅适用于变量,不适用于常量。

我们可以使用值设置可选选项,如果程序需要设置为nil,则将它们重置为nil。

例:

  //从先前的代码继续 
someOptional1 = 766
someOptional3 = 7123.98
someOptional4 = falsesomeOptional1 =无
someOptional4 = nilsomeOptional1
someOptional2
someOptional3
someOptional4

请注意,在Objective C中找不到可选参数。尽管我们可以在Objective-C中将对象设置为nil,但在Objective-C中,nil指向空指针,而在Swift中,我们可以将任何数据类型设置为可选参数。

我们还可以同时声明和分配可选内容。 请注意,此处的数据推断无效,因为可选参数被认为与String,Int,Bool或Double不同。 下面的例子:

  var someOptional5:Int?  = 823 
让someOptional6:Bool? =错误
var someOptional7:Double?
让someOptional8:String吗? =“固定词” someOptional5
someOptional6
someOptional7
someOptional8

从上面的示例可以看到,如果我们未能分配数据,则默认情况下该变量将设置为nil。

请注意,当我们声明常量可选时,系统将不会如上所述初始化为默认值。 声明为不带数据的可选项将使常数保持在可能的错误状态。 请参见下面的示例:

 让someOptional9:Bool?  =无 
让someOptional10:Int?
让someOptional11:Double吗?
让someOptional12:String吗? =“这是文本” someOptional9
// someOptional10
//尝试从someOptional10访问数据将产生错误///我们必须首先分配声明的变量
someOptional10 = 1242
someOptional11 =无//访问数据
someOptional9
someOptional10
someOptional11
someOptional12

当我们将数字从字符串转换为整数时,它会自动作为可选返回。 当我们从字符串转换为整数时,由于字符串中的值可能不包含有效数字,因此分配给该整数的声明会自动声明为可选值。 系统自动将转换后的变量分配为可选变量

在下面的示例中,由于将102写入为1o2,所以从文本到整数的转换失败。 可选整数,因为转换失败,因此将常量常量设置为nil。

例:

 让someText2 =“ 214585” 
让someNumber2 = Int(someText2)let someText3 =“ 214565s785”
让someNumber3 = Int(someText3)

我们可以使用if语句和比较操作来检查可选项,以查看其是否为nil。

例:

 让someText4 =“ 214585” 
让someNumber4 = Int(someText4)如果someNumber4!= nil {
print(“ someText4的转换成功。”)
}其他{
打印(“转换someText4失败”)
}让someText5 =“ 214565s785”
让someNumber5 = Int(someText5)如果someNumber5!= nil {
print(“ someText5的转换成功。”)
}其他{
打印(“转换someText5失败”)
}

术语“ 强制展开可选”用于从可选中提取数据。 当我们使用强制展开时,我们告诉系统我们确定可选组件包含数据,并且我们希望提取该数据。 因此,如果不检查nil值,则不应使用强制展开。

强制展开选项是通过在变量后面添加展开指示器( )来起作用的。 使用指标,我们告诉系统我们知道可选项中有值,因此我们希望提取其数据。

我们应该将强制展开与if语句一起使用,以检查可选参数是否具有值。 当我们将字符串插值与可选参数一起使用时,我们需要使用强制展开来提取数据。

使用前面的示例,我们将强制展开可选选项:

 让someText6 =“ 214585” 
让someNumber6 = Int(someText6)如果someNumber6!= nil {
print(“转换为someText6为\(someNumber6!)。”)
}其他{
print(“转换为someText6失败”)
}让someText7 =“ 214565s785”
让someNumber7 = Int(someText7)如果someNumber7!= nil {
print(“转换为someText7为\(someNumber7!)。”)
}其他{
print(“ someText7的转换失败”)
}

以下示例将说明我们使用可选数据传输数据时发生的情况。 当我们将可选内容分配给另一个变量或常量时,它将变为可选内容

 让someOptionals13:Int?  = 104让someOutput1 = someOptionals13 
 让someOptionals14:String吗?  = nillet someOutput2 = someOptionals14 

但是, 如果我们使用强制展开。 分配的常量或变量将被解释为非可选的,因为我们强制展开了可选的包装。 因此,使用强制展开类似于“ 我们知道可选项中有数据,请将可选项视为非可选项 ”。

 让someOptionals15:Int?  = 104让someOutput3 = someOptionals15! 

上面的示例仅用于说明目的。 不建议在不检查nil的情况下使用强制展开。 毕竟,使用可选参数的目的是因为没有价值的可能性。

下面的示例显示了在包含nil值的情况下强制拆开可选内容时发生的情况。

下面显示了当我们在不检查nil的情况下在字符串插值中使用强制展开时。

结论是,在不检查nil的情况下,我们不应使用强制展开。 只有极少数情况需要强制展开。

通过将optionalslet关键字和if语句结合使用,我们只有在optionals中有值时才能执行检查和执行指令。 可选绑定更安全地使用,我们不必执行强制拆包。

语法如下:

如果让 = {

}

例:

在此程序中,我们可以检查转换是否成功,如下所示:

 如果让inputValue1 = Int(someInput1){ 
print(“转换成功!转换后的数字为\(inputValue1)”)
//继续其他执行
}其他{
打印(“转换失败”)
}

请注意,语句let inputValue1 = Int(someInput1)如果不在前面,则会将inputValue1分配为可选值。 但是,如果通过在let语句前添加if语句来使用可选绑定,则系统会将inputValue1分配为整数。 即使转换失败,也不会产生错误,因为if语句用作保护或检查机制。 系统将不会创建常量inputValue1。 另请注意,不需要强制展开。

如果转换失败,我们可以跳入修复指令以正常退出程序。 使用相同的示例,我们创建一个如下所示的类型:

 如果让inputValue1 = Int(someInput1){ 
print(“转换成功!转换后的数字为\(inputValue1)”)
//继续其他执行
}其他{
打印(“转换失败”)
}

请注意,inputValue1仍然是整数。 当转换失败时,if语句将优雅地忽略转换并跳转到else语句。

可选的绑定告诉系统如果Int转换成功,则将转换后的数字传递给常量并执行if括号内包含的语句。 但是,如果转换失败,则在if括号内包含else语句。

还请注意,我们还可以在可选绑定中使用变量而不是常量。 要在可选绑定中使用变量,请使用(if var)代替(if let)。

我们还可以使用可选绑定包括更复杂的条件评估语句。

 让numberOne =“ 8872” 
如果让firstNumber = Int(numberOne),让secondNumber = Int(numberTwo),firstNumber> secondNumber {
print(“ \(firstNumber)> \(secondNumber)。仅此而已。”)
}其他{
print(“ numberOne或numberTwo转换失败,或者NumberTwo大于NumberOne。”)
}

如果一个数字转换失败或第二个数字大于第一个,它将打印else消息。

请注意,使用可选绑定创建的常量或变量仅在if语句的主体中可用。 在前面的示例中,我们不能在else语句中使用常量。 我们只能在if语句中使用常量。

我们定义可选内容是因为可选内容中可能没有任何值。 我们使用if语句或可选绑定来检查并确认可选选项中是否有值。 但是,在某些情况下,我们知道一旦设置了可选选项,就必须有一个值。 在这种情况下,我们可以定义隐式展开的可选。 我们使用以下语法声明了隐式解包的可选变量:

let / var :!

例:

  //:游乐场—名词:人们可以玩耍的地方 
导入UIKitvar someImplicitOptionals:Int!
func初始化(){
someImplicitOptionals = 10
}初始化()
打印(someImplicitOptionals)

在上面的示例中,我们创建了一个具有隐式展开功能的可选内容,因为我们知道执行初始化函数后,optonal中必须有一个值。 注意,在打印变量时,我们不需要使用强制展开。

如果程序无法运行初始化会怎样? 该变量将默认为可选。

这样,我们可以使用隐式解包的可选对象,而无需使用任何强制解包。 如果初始化失败,则该变量将作为可选变量回退。 不会产生错误。

以下示例将进一步说明可选选项和隐式包装的可选选项之间的区别。

 让someOptionals100:Int?  = 10928 
print(someOptionals100!)let someImplicitOptional100:Int! = someOptionals100
打印(someImplicitOptional100)

如上所示,在处理可选内容时,我们可能需要使用强制展开,而我们可以像普通变量一样使用隐式展开的可选内容。

请注意,当我们在不能接受nil的情况下使用隐式解包的optional时,如果没有任何值,它将生成运行时错误。 因此,使用可选绑定或使用if语句排除nil是一个好习惯。

例:

继续上一个示例

  //继续上一个示例 
如果让checkImplicitOptional = someImplicitOptional100 {
print(“此可选数字\(checkImplicitOptional)一切正常,”)
}让someWrongImplicitOptional:Int! =无
如果让checkImplicitOptional = someWrongImplicitOptional {
print(“第二个可选数字\(checkImplicitOptional)一切都很好”)
}其他{
print(“出问题了。这个数字似乎为空。”)
}

在上面的示例中,使用了可选绑定来检查隐式解开的可选是否为nil。

隐式展开的可选对象在处理类时的主要应用是初始化和使用类对象。 当我们讨论类和对象时,我们将进一步讨论。

总而言之,在处理可选内容时,请注意以下几点:

  • 当我们知道您的变量或常量中可能没有值(零)时,请使用可选。 用?附加数据类型 用于可选。
  • 当我们知道程序加载后,变量将包含数据时,请使用隐式解包的可选变量。
  • 请使用可选的绑定或简单的if语句来检查nil(在使用此语句时需要一些值,以避免运行时错误)。
  • 请使用可选绑定或简单的if语句来声明可选和隐式展开的可选。

最初于 2018 年4月19日 发布在 blog.swifticode.com 上。