Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.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 什么';如果为零,两者之间的区别是什么可选…;如果让u=可选…;_Swift_Optional - Fatal编程技术网

Swift 什么';如果为零,两者之间的区别是什么可选…;如果让u=可选…;

Swift 什么';如果为零,两者之间的区别是什么可选…;如果让u=可选…;,swift,optional,Swift,Optional,我需要测试返回可选值的表达式是否为nil。这看起来很简单,但代码如下 if nil != self?.checklists.itemPassingTest({ $0 === note.object }) { … } 不知什么原因,我觉得它很不舒服 if let item = self?.checklists.itemPassingTest({ $0 === note.object }) { … } 看起来好多了,但我其实不需要这个东西,我只需要知道有没有退货。因此,我使用了以

我需要测试返回可选值的表达式是否为
nil
。这看起来很简单,但代码如下

if nil != self?.checklists.itemPassingTest({ $0 === note.object }) {
    …
}
不知什么原因,我觉得它很不舒服

if let item = self?.checklists.itemPassingTest({ $0 === note.object }) {
    …
}
看起来好多了,但我其实不需要这个东西,我只需要知道有没有退货。因此,我使用了以下方法

if let _ = self?.checklists.itemPassingTest({ $0 === note.object }) {
    …
}
我是不是错过了一些微妙的东西?我认为
如果为零!=可选…
如果let=可选…
在这里是等效的


更新以解决答案中的一些问题

  • 我看不出
    nil!=var
    var!=nil
    ,尽管我通常使用
    var!=无
    。在这种情况下,按
    !=nil
    在块获得与if的布尔比较混合的块的布尔比较后

  • 使用不应该那么令人惊讶或不常见。它们用于元组
    (x,)=(10,20)
    ,用于循环
    ,用于1…5
    ,case语句
    case(0):
    ,等等(注意:这些示例取自Swift编程语言)

  • 这个问题是关于这两种形式的功能等价性,而不是关于编码风格的选择。该对话可在programmers.stackexchange.com上进行


    经过这么长时间,Swift 2.0让它变得毫无意义

    if self?.checklists.contains({ $0 === note.object }) ?? false {
        …
    }
    

    我个人认为这看起来令人不快,因为您将零与结果进行比较,而不是将结果与零进行比较:

    if self?.checklists.itemPassingTest({ $0 === note.object }) != nil {
        …
    }
    

    由于您只想确保它不是nil,并且不使用
    ,因此使用
    let
    是没有意义的,如果let语法被称为可选绑定。它接受一个可选项作为输入,如果可选项不是nil,则返回一个必需的常量。这适用于公共代码模式,首先检查一个值是否为nil,如果它不是nil(如果它有一个值),则对其执行一些操作

    如果可选的nil,则停止处理,并跳过大括号内的代码

    如果可选!=nil
    语法更简单。它只是检查可选值是否为nil。它会跳过为您创建所需的常量

    如果您不打算使用结果值,那么可选的绑定语法是浪费和混乱的。如果可选,请使用更简单的
    在这种情况下为零。正如nhgrif所指出的,它生成的代码更少,而且您的意图更加清晰

    编辑:
    如果您编写“if-let”可选绑定代码,但最终不使用绑定的变量,那么编译器似乎足够聪明,不会生成额外的代码。主要区别在于可读性。使用可选绑定会产生一种期望,即您将使用绑定的可选绑定。

    优化后,这两种方法可能是相同的

    例如,在本例中,使用
    swiftc-O-emit assembly if_let.swift
    编译以下两个组件:

    import Darwin
    
    // using arc4random ensures -O doesn’t just
    // ignore your if statement completely
    let i: Int? = arc4random()%2 == 0 ? 2 : nil
    
    if i != nil {
      println("set!")
    }
    
    vs

    生成相同的程序集代码:

        ; call to arc4random
        callq   _arc4random
        ; check if LSB == 1 
        testb   $1, %al
        ; if it is, skip the println
        je  LBB0_1
        movq    $0, __Tv6if_let1iGSqSi_(%rip)
        movb    $1, __Tv6if_let1iGSqSi_+8(%rip)
        jmp LBB0_3
    LBB0_1:
        movq    $2, __Tv6if_let1iGSqSi_(%rip)
        movb    $0, __Tv6if_let1iGSqSi_+8(%rip)
        leaq    L___unnamed_1(%rip), %rax  ; address of "set!" literal
        movq    %rax, -40(%rbp)
        movq    $4, -32(%rbp)
        movq    $0, -24(%rbp)
        movq    __TMdSS@GOTPCREL(%rip), %rsi
        addq    $8, %rsi
        leaq    -40(%rbp), %rdi
        ; call println
        callq   __TFSs7printlnU__FQ_T_
    LBB0_3:
        xorl    %eax, %eax
        addq    $32, %rsp
        popq    %rbx
        popq    %r14
        popq    %rbp
        retq
    

    空速的答案告诉我们,
    !=nil
    生成相同的汇编代码,因此我强烈建议使用第一种方法

    事实上,如果你有以下情况:

    if let _ = optional {
        do_something()
    }
    
    …并且您希望添加一些代码,现在您需要该可选代码,此更改将更容易、更快:

    if let wrapped = optional {
        do_something()
        do_something_else(with: wrapped)
    }
    

    使用
    let
    并编写可维护的代码。

    func-check(x:Int){/*arc4random()->x*/}
    将输出从1000页减少到1.5页。:-)在这个例子中,我并不关心性能,但知道它们具有等效的二进制表示让我放心。考虑到苹果的swift示例中使用了of,我不认为一个未绑定的变量应该那么令人惊讶。正如这张海报所说,正如我在上面的另一篇评论中所说,源代码是人类可读的代码,因此应该表达人类如何表达逻辑。大声读出逻辑,它会说‘如果这不是零,那么……’,这准确地翻译为‘如果x!’无{…’在源代码中,这意味着更具可读性。老实说,我看不出“if let ux”对它有什么好处。也许这只是当你不关心一个或多个值时,能够进行模式匹配的副产品,为了支持这一点,它最终创建了“if let x”的废话。
    对于范围内的
    是一个very不同的情况。在这种情况下,您运行循环的次数是特定的,但不需要索引值。我正要投票支持这个,但后来我想到了什么是源代码…人类可读的代码。虽然您是对的,如果您需要该值,将来更容易更改,但从其他语法更改也不难.更重要的是,在那之前(如果有的话),它不那么可读。想想看……大声读逻辑,它说‘如果这不是零,那么……’,这在源代码中准确地翻译为‘如果x!=nil{…’,这意味着它更可读。这就是为什么我改变了主意。
    if let wrapped = optional {
        do_something()
        do_something_else(with: wrapped)
    }