Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 为什么空检查不好/如果可选项';什么是空的?_Swift_Kotlin_Null_Optional - Fatal编程技术网

Swift 为什么空检查不好/如果可选项';什么是空的?

Swift 为什么空检查不好/如果可选项';什么是空的?,swift,kotlin,null,optional,Swift,Kotlin,Null,Optional,我已经阅读了一些类似问题的答案和一些教程,但没有一本能解决我的主要困惑。我是本地Java程序员,但我也用Swift编程 为什么我要用可选的而不是空的 我读过这样的文章,它减少了空检查和错误,但是这些都是必要的,或者可以通过干净的编程轻松避免 我也读过,所以所有的引用都成功了(而且val length=text?.length)。但我认为这是一件坏事或用词不当。如果我调用length函数,我希望它包含一个长度。如果没有,代码应该在那里处理它,而不是继续 我遗漏了什么?选项提供了清晰的类型。Int存

我已经阅读了一些类似问题的答案和一些教程,但没有一本能解决我的主要困惑。我是本地Java程序员,但我也用Swift编程

为什么我要用可选的而不是空的

我读过这样的文章,它减少了空检查和错误,但是这些都是必要的,或者可以通过干净的编程轻松避免

我也读过,所以所有的引用都成功了(而且
val length=text?.length
)。但我认为这是一件坏事或用词不当。如果我调用length函数,我希望它包含一个长度。如果没有,代码应该在那里处理它,而不是继续


我遗漏了什么?

选项提供了清晰的类型。Int存储实际值-始终,而可选Int(即Int?)存储Int或nil的值。可以说,这种显式的“dual”类型允许您创建一个简单的函数,该函数可以清楚地声明它将接受和返回什么。如果您的函数只是简单地接受一个实际的Int并返回一个实际的Int,那么就太好了

func foo(x: Int) -> Int
但是,如果您的函数希望允许返回值为nil,参数为nil,则必须显式将其设置为可选:

func foo(x: Int?) -> Int?
在其他语言(如Objective-C)中,对象可以始终为零。C++中的指针也可以是零。因此,在Obj-C中接收的任何对象或C++中接收的任何指针都应该被检查为零,以防您的代码所期望的不是(真实对象或指针)。 在Swift中,关键是您可以声明非可选的对象类型,因此您将这些对象交给的任何代码都不需要进行任何检查。他们可以安全地使用这些对象,并且知道它们是非空的。这是Swift optionals的一部分力量。如果您收到一个可选的,那么当您需要访问它的值时,您必须显式地将它解压为它的值。那些使用Swift编写代码的人总是尽可能地将其函数和属性设置为非可选的,除非他们确实有理由将其设置为可选的

Swift optionals的另一个优点是所有用于处理optionals的内置语言结构,使代码编写更快、阅读更清晰、更紧凑。。。省去了很多麻烦,不用检查和解包一个可选的和等价的,你必须用其他语言做的

nil凝聚算子(??)是一个很好的例子,如if-let和guard等

总之,optionals鼓励并强制在代码类型检查中执行更显式的类型检查,这是由编译器而不是在运行时完成的。当然,你可以用任何语言编写“干净”的代码,但用Swift编写代码要简单得多,自动化程度也更高,这在很大程度上要归功于它的可选代码(以及非可选代码!)

  • 避免编译时出错。这样就不会无意中传递空值

  • 在Java中,任何变量都可以为null。因此,在使用它之前检查null已成为一种惯例。在swift中,只有可选项可以为空。因此,您必须只检查可选的可能空值

  • 您不必总是检查可选项。您可以同样很好地处理选项,而无需展开它们。将方法发送到具有null值的optional不会破坏代码


  • 可以有更多,但这些是非常有用的。

    TL/DR:编译器也可以更严格地避免使用干净编程可以避免的空检查。您所说的必要的空检查可以由编译器以更严格的方式强制执行。Optionals是使之成为可能的类型构造


    var length=text?.length

    这实际上是一个很好的例子,说明了可选项是有用的。如果文本没有值,那么它也不能有长度。在Objective-C中,如果
    text
    为零,则您发送的任何消息都不会执行任何操作,并返回0。这一事实有时是有用的,它可以跳过大量的零检查,但也可能导致微妙的错误

    另一方面,许多其他语言指出了这样一个事实:当代码执行时,通过立即崩溃,您已经向nil指针发送了一条消息。这使得在开发过程中更容易发现问题,但是当运行时错误发生在用户身上时,就不会那么严重了

    Swift采取了一种不同的方法:如果
    文本
    没有指向有长度的东西,那么就没有长度。可选的不是指针,而是一种有值或无值的类型。您可以假设变量
    length
    是一个
    Int
    ,但实际上它是一个
    Int?
    ,这是一种完全不同的类型

    如果我调用length函数,我希望它包含一个长度。如果没有,代码应该在那里处理它,而不是继续

    如果
    text
    为nil,则没有对象可向其发送
    length
    消息,因此
    length
    甚至从未被调用,结果为nil。有时这很好——如果没有
    文本
    ,也就不可能有
    长度
    ,这是有道理的。您可能不在乎这一点-如果您准备在
    文本中绘制字符
    ,那么没有
    长度
    这一事实不会困扰您,因为反正没有什么可绘制的。
    text
    length
    的可选状态迫使您处理这样一个事实,即这些变量在您需要值的地方没有值

    让我们看一个更具体的版本:

    var text : String? = "foo"
    var length : Int? = text?.count
    
    这里,
    text
    有一个值,因此
    length
    也会得到一个值,但是
    length
    仍然是可选的,所以在
    var text : String? = nil
    var length : Int? = text?.count
    
    var text : String? = "foo"
    var length : Int = text.count
    
    var text : String? = "foo"
    var length : Int = text!.count
    
    var text : String? = nil
    var length : Int = text!.count
    
    error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    
    var text : String = "foo"
    var length : Int = text.count