我需要测试一个返回一个可选项的表达式nil.这看起来很简单,但这里是代码.
if nil != self?.checklists.itemPassingTest({ $0 === note.object }) {
…
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,我的眼睛看起来很不愉快.
if let item = self?.checklists.itemPassingTest({ $0 === note.object }) {
…
}
Run Code Online (Sandbox Code Playgroud)
看起来好多了,但我实际上并不需要这个项目,我只需要知道是否有人退回.所以,我使用了以下内容.
if let _ = self?.checklists.itemPassingTest({ $0 === note.object }) {
…
}
Run Code Online (Sandbox Code Playgroud)
我错过了一些微妙的东西吗?我认为if nil != optional …并且if let _ = optional …相当于此.
更新以解决答案中的一些问题
我不明白之间的差别nil != var和var != nil,虽然我一般使用var != nil.在这种情况下,按下!= nil块之后获取混合的块的布尔比较和if的布尔比较.
使用通配符模式不应该是令人惊讶或不常见的.它们用于元组(x, _) = (10, 20),for-in循环for _ in 1...5,case语句case (_, 0):等(注意:这些示例来自Swift编程语言).
这个问题是关于两种形式的功能等同性,而不是关于编码风格选择.那个对话可以在programmers.stackexchange.com上进行.
经过这么长时间,Swift 2.0让它变得毫无意义
if self?.checklists.contains({ $0 === note.object }) ?? false {
…
}
Run Code Online (Sandbox Code Playgroud)
Air*_*ity 21
优化后,这两种方法可能是相同的.
例如,在这种情况下,使用以下内容编译以下内容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!")
}
Run Code Online (Sandbox Code Playgroud)
VS
import Darwin
let i: Int? = arc4random()%2 == 0 ? 2 : nil
if let _ = i {
println("set!")
}
Run Code Online (Sandbox Code Playgroud)
生成相同的汇编代码:
; 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
Run Code Online (Sandbox Code Playgroud)
Dun*_*n C 16
该if let语法被称为可选的绑定.它需要一个可选的输入,如果optional不是nil,则返回一个必需的常量.这适用于常见的代码模式,您首先检查值是否为nil,如果不是,则使用它执行某些操作.
如果optional 是 nil,则处理停止并跳过大括号内的代码.
该if optional != nil语法比较简单.它只是检查可选项是否为零.它会跳过为您创建所需的常量.
如果您不打算使用结果值,则可选的绑定语法会浪费并且令人困惑.if optional != nil在这种情况下使用更简单的版本.正如nhgrif指出的那样,它产生的代码更少,而且你的意图更清晰.
听起来好像编译器足够智能,如果您编写"if let"可选绑定代码但不会最终使用您绑定的变量,则不会生成额外的代码.主要区别在于可读性.使用可选绑定会产生期望您将使用绑定的可选项.
我个人认为这看起来很不愉快,因为你将nil与结果进行比较而不是将结果与nil进行比较:
if self?.checklists.itemPassingTest({ $0 === note.object }) != nil {
…
}
Run Code Online (Sandbox Code Playgroud)
因为你只想确保它不是零并且不使用,item所以没有必要使用let.
| 归档时间: |
|
| 查看次数: |
5002 次 |
| 最近记录: |