【问题标题】:I still can't understand Optionals我还是看不懂 Optionals
【发布时间】:2018-01-12 04:03:08
【问题描述】:

我是 Swift 语言 的新手,在此之前我只从事 Web 开发。

我试图掌握可选项的概念,但是每次他们提出一些使用它的情况时,我仍然无法理解他们为什么这样做(或者我可能有一点想法,但仍不确定。)

我阅读了几篇关于此的文章,也许我只是在此过程中太困惑而迷路了。

让我们举一些例子。假设我有一个带有 textfield 的电子邮件注册表单。发送表单后,在 PHP 中我可以执行以下操作:

$mail = $_POST['mail'];

if($mail == "") { 
    echo "ERROR: The E-mail is empty";
} else {
    // Do something more
}

如果文本字段为空,则 $_POST['mail'] 的值为空字符串。我可以使用它并检查它是否为空。

现在,如果我理解正确,那么该文本字段的值很快就不会是空字符串,而实际上是 nil,对吧?这就是我们需要选项的区别吗?因为与 PHP 相比,在 Swift 中我每次都必须声明该信息的类型,并且它不知道该文本字段是传递字符串还是数字?

让我们谈谈另一个例子。 swift 中的很多人只是将一个字符串声明为可选,即使他们在其中输入了一个值,如下所示:

let name:String? = "Gabriel"

如果它已经有一个值,那为什么还要让它成为可选的呢?对我来说,它只是一个带有值的普通常量,我看不出将它包装成可选项的意义。

如果我不知道声明中的名称,为什么不能直接输入?

let name:String = ""

然后,我可以使用 if 语句来检查它是否为空

if name == "" {
  print("ERROR: name is empty")
} else {
  //Do something else
}

我对文本字段的想法是否正确? 我有什么遗漏吗?

感谢您的帮助!

编辑(是什么让我理解了这个概念):

我最困惑的是一个简单的事实,例如 String 只能存储“文本”,如果 nil 是什么,它就不是 String 类型,所以因此 它当然不能“存储”在 String 中

同样,我不能将文本存储到整数中——我不能将零“存储”到字符串中。

但是使用可选字符串,我可以使用这个 "wrapper" 实际上 CAN “存储”两种类型:字符串或 nil。这就是常规字符串与可选字符串的区别。正是这个“包装器”能够“持有”这两种类型,直到我需要使用实际值。 (现在我当然明白了,nil 实际上是没有任何值的。我只是这样用它来说明这一点)

感谢大家的帮助!

【问题讨论】:

  • 可选意味着该值在某些时候可以是nil,即使您在声明时赋予它值,并且在读取时您必须检查它是否为 nil 或具有值,非可选意味着它永远不能是nil,如果 nil 并且读取它会崩溃
  • 但是检查 nil 与检查空值的问题是一样的。要检查字符串是否为空或 Int == 0,就像我可以检查某些东西是否 == nil 一样,我不需要选项,只需要一个 if 语句。
  • 不同的是,0 不是 nil,0 表示值为 0,nil 表示它在物理内存中根本没有任何值,只是一个空指针

标签: php ios swift


【解决方案1】:

假设您从 ebay 订购了一个游戏机。你首先看到的不是游戏机,而是一个盒子。因此,在这种情况下,该框是可选的。让我们写下来。

var playstation: Playstation?

盒子当然可以是空的。为了使用 playstation,我们需要打开盒子。我们有几种方法可以做到这一点。

安全的方法:

if let ps = playstation {
  // if the box is not empty, and the PS is there
  ps.play()
} else {
  print("The box was empty :(")
}

另一种方式:

playstation?.play()

在另一种情况下,我们仅在 playstation box 的内容不为空时才调用 play() 方法。缺点是如果失败,您将无法显示错误。

如果您向您的朋友承诺,您将在今天将出现的游戏机上一起玩会怎样。您保证游戏机将在包装盒中。那是你使用这个的时候:

playstation!.play()

这种方法的问题是,在实际程序中,如果可选项的内容为空,您的应用会崩溃。利用 ”!”仅当您可以保证它不会为空时(即您在此之前为变量分配了一个值)

因此,总而言之,可选项是其值可以是特定类型(即字符串)或 nil 的变量。您不能将 nil 分配给强类型变量。

var a: String?
var b: String

a = nil // this is ok
b = nil // this will not compile

【讨论】:

  • 实际上最后一句话可能对我来说终于有意义了。问题是字符串只存储字符串,整数只存储数字。但是一个可选的字符串可以“存储” String 和 Nil(在某种程度上)。因为就像我不能声明 let number:Int = "String" 一样,我不能在变量中没有值。所以这就是为什么我需要可选的类型,准备好我可能不会得到类型字符串,但也是一个“类型”nil(如果它是一个类型)
  • 如果您需要更多关于 nil 是什么的详细信息,可以查看这篇文章。 nshipster.com/swift-literal-convertible
  • 这是否意味着我理解正确?我一直都在错过“简单”点吗?只是String只能处理“text”,而Optional String在必要时可以同时处理“Text”和Nil?
  • 是的,但是你需要解开可选的文本才能使用文本,否则打印出来的时候值会是 Optional("your text")。请参阅上面的 3 个示例,了解如何展开。
  • 是的,我了解包装。我认为对我来说主要的困惑是事实,我不能把 nil 放在 String 中,只是文本。如果我试图把 nil 放在那里,它会崩溃。但是 Optional String 给了我这个 String 或 Nill 的包装器。使用普通字符串是不可能的。当然,为了在最后使用这个值,我必须打开它(最好使用可选绑定)
【解决方案2】:

想想这样的选项:

可选项是一个变量,将来甚至现在都可以为空。

使变量成为可选意味着它被包装为枚举。

假设有一个变量:var x : Int?,这意味着一个名为 x 的 Int 类型的变量尚未初始化并且是可选的。

这通常可以用外行术语表示为

Enum x(optional) // name of the variable{
 case T: // some value
 case nil: // no value
}

所以当我们给变量赋值的时候我们可以正常赋值,但是值是存储在x的可选枚举变量的case T中

x = 10 // 
enum x(optional){
     case T = 10
     case nil 
 }

当我们想使用它时(获取值)我们使用 (?) 或 (!)

这些可以进一步解释为

print(x?) // 如果x里面有任何值,给我(这里给我x的T情况下的值)

print(x!) // 我不管x里面有没有值,反正给我就行了。

因此,如果 x 没有值,则打印 (x!) 将产生崩溃,因为 x 内部没有值。

? - 安全地展开可选的

! - 强制解开可选的

P.S - 我知道我错过了某些事情,但这是 Optional 的要点,这仅用于解释目的。一旦你掌握了这个概念,你可以进一步查看更多关于 Apple 文档here的文档

【讨论】:

    【解决方案3】:

    实际上,

    let name:String? = "Gabriel"
    

    不是很有用。 但是

    var name:String? = "Gabriel"
    

    确实有意义,因为您可以进一步设置为 nil。

    选项对于从函数返回值非常有用。 考虑一个返回 Int 的函数。

    如果未找到该值,您可以返回一个数字(如非常大的负数)以通知未找到该值。但是总有一天 func 确实会返回这个值(甚至不太可能)。 返回一个 nil 让函数清楚地表明它没有找到该值。

    【讨论】:

      【解决方案4】:

      我对可选项的理解是,它们是一种类似于 String、Int 或 Double 的类型。选项有关联的值,所以一个字符串?是一个可选的,带有与之关联的字符串。可选项可以包含一个字符串的值,甚至是一个空字符串,或者根本没有,这对我来说是空的。查看 iTunes 上的斯坦福大学 IOS 课程。选项的解释比我能解释的要好得多。

      【讨论】:

        猜你喜欢
        • 2017-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-20
        • 1970-01-01
        • 2022-01-10
        • 2023-03-10
        • 1970-01-01
        相关资源
        最近更新 更多