在Swift中使用具有相同变量名的可选绑定

时间:2022-09-11 18:29:46

I am learning Swift. I came across these lines of code in a book.

我正在学习迅速。我在一本书中偶然发现了这些代码。

import UIKit

var errorCodeString : String?  
errorCodeString = "404"  
var errorDescription : String?

if let theError = errorCodeString, 
    let errorCodeInteger = Int(theError), 
    errorCodeInteger == 404 {

    errorDescription = "\(errorCodeInteger + 200) : resource was not found." 
}

var upCaseErrorDescription = errorDescription?.uppercased()
errorDescription

upCaseErrorDescription?.append("PLEASE TRY AGAIN") 
upCaseErrorDescription

errorDescription = nil 
let description: String  
if let errorDescription = errorDescription { 
    description = errorDescription 
} else { 
    description = "NO ERROR" 
}

For this line:

这条线:

if let errorDescription = errorDescription

errorDescription has been declared as a variable from the beginning and declared again as a constant.
I am a bit confused here. Are these two "errorDescription" the same?

errorDescription从一开始就被声明为变量,然后又被声明为常量。我有点困惑。这两个“错误描述”是一样的吗?

2 个解决方案

#1


1  

I am a bit confused here. Are these two "errorDescription" the same?

我有点困惑。这两个“错误描述”是一样的吗?

Actually, they are not exactly the same.

实际上,它们并不完全相同。

For this case, accessing errorDescription inside the block of the if let would be referred to a new -unwrapped- constant (without the ?)

对于这种情况,在if let中访问errorDescription会被引用到一个新的-未包装的常量(没有?)

if let errorDescription = errorDescription {
   print(errorDescription)
}

Prove it!

证明它!

You don't need to do that anyway in your real app, it is just to make it clear to you.

在你真正的应用中,你不需要这么做,只是想让你明白。

If you tried to update the value of the unwrapped variable, it will not affect to original -optional- one, for example:

如果您试图更新未包装的变量的值,它不会影响到原始的-optional——例如:

var myString: String? = "Hello"

if var myString = myString {
    myString += " World"
}

print(myString) // Optional("Hello")

As you can see, myString value still the same (not "Hello World").

如您所见,myString值仍然相同(不是“Hello World”)。

Another way to prove that they are not the same: If you are declaring it in a class/struct, you can let the compile to recognize between your instance variable and the unwrapped constant by using self:

另一种证明它们不相同的方法是:如果在类/结构中声明它,可以使用self让compile识别实例变量和未包装的常量:

struct MyStruct {
    var myString: String? = "Hello"

    func sayHello() {
        if var myString = myString {
            myString += " World" // here is the unwrapped constant ("Hello World")
            print(self.myString) // here is the instance variable ("Optional("Hello")\n")
        }
    }
}

#2


0  

First of all, you have to understand the concept of Optional, from Apple Docs:

首先,你必须从苹果文档中理解可选的概念:

A type that represents either a wrapped value or nil, the absence of a value.

一种类型,表示一个已包装的值或nil值的缺失。

So if the Optional variable has a value of that type that can be unwrapped, it contains that value. If it doesn't, it contains nil.

因此,如果可选变量具有可以打开的那种类型的值,则它包含该值。如果没有,它包含nil。


Let's say you have the following code:

假设您有以下代码:

let string: String? = "dog"

As you can see, an optional String has been created, using the optional operator ?. If you now try to print it:

如您所见,使用可选操作符创建了一个可选的字符串。如果你现在尝试打印它:

print(string) 

the output will be: Optional("dog"). That is because this optional string has not been unwrapped. A way to unwrap it is using the if-let pair, as below:

输出将是:可选的(“dog”)。这是因为这个可选字符串还没有被打开。打开它的一种方法是使用if-let对,如下所示:

if let string = string{ print(string) }

This will now output dog. But why? - When you declare a let constant in the structure of an if-statement, a copy of the original value is created, and if the value was previously nil, then the if-statement doesn't execute at all, because the condition will be false. So you are guaranteed that if the code inside the if let statement executes, then the newly-created constant will contain the successfully unwrapped value of the original variable.

这将输出dog。但是为什么呢?-当您在if语句的结构中声明一个let常量时,将创建原始值的副本,如果该值以前为nil,则if语句根本不会执行,因为条件将为false。因此,如果执行if let语句中的代码,那么新创建的常量将包含原始变量的已成功展开的值。


"I am a bit confused here. Are these two errorDescription the same?"

“我有点糊涂了。”这两个错误的描述是一样的吗?

No, they are not. They just happen to have the same name. You can choose any other name for the newly created constant.

不,他们不是。他们只是碰巧有相同的名字。您可以为新创建的常量选择任何其他名称。

Now that this things are clear, there is one more thing to be explained. When using the let constant declared in the if-condition, you refer to it as: value. When one wants to access the original optional (inside the if), it is referred as: self.value!.

既然事情已经很清楚了,还有一件事需要解释。当使用if条件中声明的let常量时,您将其引用为:value。当您想访问原始的可选(在if中)时,它被称为:self.value!


There are other ways to unwrap an optional as well:

还有其他的方法来打开一个可选的:

  • guard let statements - should only be used inside functions or loops

    保护声明-应该只在函数或循环中使用。

  • if value != nil{} + force-unwrapping, because you are certain that the value is not nil.

    如果值!= nil{} +强制展开,因为您确定该值不是nil。


You can learn more about Optionals at The Swift Programming Language (Swift 3.1): The Basics

您可以通过Swift编程语言(Swift 3.1)了解更多关于选项的信息:基础

#1


1  

I am a bit confused here. Are these two "errorDescription" the same?

我有点困惑。这两个“错误描述”是一样的吗?

Actually, they are not exactly the same.

实际上,它们并不完全相同。

For this case, accessing errorDescription inside the block of the if let would be referred to a new -unwrapped- constant (without the ?)

对于这种情况,在if let中访问errorDescription会被引用到一个新的-未包装的常量(没有?)

if let errorDescription = errorDescription {
   print(errorDescription)
}

Prove it!

证明它!

You don't need to do that anyway in your real app, it is just to make it clear to you.

在你真正的应用中,你不需要这么做,只是想让你明白。

If you tried to update the value of the unwrapped variable, it will not affect to original -optional- one, for example:

如果您试图更新未包装的变量的值,它不会影响到原始的-optional——例如:

var myString: String? = "Hello"

if var myString = myString {
    myString += " World"
}

print(myString) // Optional("Hello")

As you can see, myString value still the same (not "Hello World").

如您所见,myString值仍然相同(不是“Hello World”)。

Another way to prove that they are not the same: If you are declaring it in a class/struct, you can let the compile to recognize between your instance variable and the unwrapped constant by using self:

另一种证明它们不相同的方法是:如果在类/结构中声明它,可以使用self让compile识别实例变量和未包装的常量:

struct MyStruct {
    var myString: String? = "Hello"

    func sayHello() {
        if var myString = myString {
            myString += " World" // here is the unwrapped constant ("Hello World")
            print(self.myString) // here is the instance variable ("Optional("Hello")\n")
        }
    }
}

#2


0  

First of all, you have to understand the concept of Optional, from Apple Docs:

首先,你必须从苹果文档中理解可选的概念:

A type that represents either a wrapped value or nil, the absence of a value.

一种类型,表示一个已包装的值或nil值的缺失。

So if the Optional variable has a value of that type that can be unwrapped, it contains that value. If it doesn't, it contains nil.

因此,如果可选变量具有可以打开的那种类型的值,则它包含该值。如果没有,它包含nil。


Let's say you have the following code:

假设您有以下代码:

let string: String? = "dog"

As you can see, an optional String has been created, using the optional operator ?. If you now try to print it:

如您所见,使用可选操作符创建了一个可选的字符串。如果你现在尝试打印它:

print(string) 

the output will be: Optional("dog"). That is because this optional string has not been unwrapped. A way to unwrap it is using the if-let pair, as below:

输出将是:可选的(“dog”)。这是因为这个可选字符串还没有被打开。打开它的一种方法是使用if-let对,如下所示:

if let string = string{ print(string) }

This will now output dog. But why? - When you declare a let constant in the structure of an if-statement, a copy of the original value is created, and if the value was previously nil, then the if-statement doesn't execute at all, because the condition will be false. So you are guaranteed that if the code inside the if let statement executes, then the newly-created constant will contain the successfully unwrapped value of the original variable.

这将输出dog。但是为什么呢?-当您在if语句的结构中声明一个let常量时,将创建原始值的副本,如果该值以前为nil,则if语句根本不会执行,因为条件将为false。因此,如果执行if let语句中的代码,那么新创建的常量将包含原始变量的已成功展开的值。


"I am a bit confused here. Are these two errorDescription the same?"

“我有点糊涂了。”这两个错误的描述是一样的吗?

No, they are not. They just happen to have the same name. You can choose any other name for the newly created constant.

不,他们不是。他们只是碰巧有相同的名字。您可以为新创建的常量选择任何其他名称。

Now that this things are clear, there is one more thing to be explained. When using the let constant declared in the if-condition, you refer to it as: value. When one wants to access the original optional (inside the if), it is referred as: self.value!.

既然事情已经很清楚了,还有一件事需要解释。当使用if条件中声明的let常量时,您将其引用为:value。当您想访问原始的可选(在if中)时,它被称为:self.value!


There are other ways to unwrap an optional as well:

还有其他的方法来打开一个可选的:

  • guard let statements - should only be used inside functions or loops

    保护声明-应该只在函数或循环中使用。

  • if value != nil{} + force-unwrapping, because you are certain that the value is not nil.

    如果值!= nil{} +强制展开,因为您确定该值不是nil。


You can learn more about Optionals at The Swift Programming Language (Swift 3.1): The Basics

您可以通过Swift编程语言(Swift 3.1)了解更多关于选项的信息:基础