swift:如果使用并行分配

swift:如果使用并行分配,swift,tuples,swift-playground,optional-values,parallel-assignment,Swift,Tuples,Swift Playground,Optional Values,Parallel Assignment,我试图用一个以上的值生成一个简单的if-let语句。仅当所有可选变量均为非nil时,才应执行if块,并且应将它们分配给仅位于if块内的新let变量(常量?),就像正常的单个赋值if let一样 var a: String? = "A" var b: String? // nil if let (m, n) = (a, b) { println("m: \(m), n: \(n)") } else { println("too bad") } // error: Bound va

我试图用一个以上的值生成一个简单的if-let语句。仅当所有可选变量均为非nil时,才应执行
if
块,并且应将它们分配给仅位于
if
块内的新let变量(常量?),就像正常的单个赋值if let一样

var a: String? = "A"
var b: String? // nil

if let (m, n) = (a, b) {
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}
// error: Bound value in a conditional binding must be of Optional type
// this of course is because the tuple itself is not an Optional
// let's try that to be sure that's the problem...

let mysteryTuple: (String?, String?)? = (a, b)
if let (m, n) = mysteryTuple {
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}
// yeah, no errors, but not the behavior I want (printed "m: A, n: nil")

// and in a different way:
if let m = a, n = b {
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}
// a couple syntax errors (even though 'let m = a, n = b'
// works on its own, outside the if statement)

这可能吗?如果不是(我猜),你认为苹果会(或应该)在将来实现这一点吗?

在决定是否可能之前,考虑为什么<代码> if -让……/Cult>条件语句使用一个可选的值:这个代码编译

的原因
if let constVar = testVar {
    ...
}
所有可选类型都符合
LogicalValue
协议,该协议处理可选值的空检查

这也解释了为什么使用可选元组的技巧也不起作用:
LogicalValue
的实现检查元组本身是否为非null,忽略其组件。苹果的决定背后的逻辑是明确的:当元组的所有元素类型都是可选的时,他们没有对元组做出例外,而是采取统一的方法,并以对待其他可选类型的相同方式对待元组

当然,通过额外的一行代码,实现您试图实现的逻辑很容易:

if a != nil && b != nil {
    let (m, n) = (a!, b!)
    println("m: \(m), n: \(n)")
} else {
    println("too bad")
}

这一点现在可能已经很明显了,但您对这一预期功能的追求可能会随着Swift 1.2的发布而结束

来自swift博客:

使用if-let-if-let构造进行更强大的可选展开 现在可以一次展开多个选项,也可以包括 中间的布尔条件。这可以让你表达条件 控制流而不进行不必要的嵌套

不过,它的缺点是,除了使用where子句约束值之外,您现在还可以按要求执行操作

if let a = foo(), b = bar() {
}

苹果将要或应该做的不是堆栈溢出的主题。重复问题的顶部答案中提到的可能重复,您可以通过
开关
语句得到它--
如果
用于二进制测试,
开关
用于n元和多维模式匹配。您是对的,我在最初的搜索中没有看到这个问题,但基本上就是这样。作业的目的是什么
let(m,n)=(a,b)
?与
if let…
相反,它不会打开选项。因此,您可以测试
如果a&&b…
@MartinR您是对的,这甚至更好,因为
m
n
的范围仍然局限于
if
语句。虽然这些值在
else
分支中不可见,但这应该不是什么大问题,因为其中一个值无论如何都是空的,因此程序必须再次单独检查它们,以便对它们执行任何有用的操作。奇怪的是,如果您将
a
b
作为
字符串键入而不是
字符串?
,该代码使编译器崩溃。出于这一原因和其他原因,应完全避免使用
if a
测试nil;相反,利用nil现在是一个文本的事实,并显式比较:
if a!=无
。这在将来可能变得更加重要,因为隐式nil测试有可能从语言中删除。您不想
让(m,n)=(a!b!)
?仅分配而不展开将给您留下两个新的可选值。@matt您说得对,谢谢您的评论!我一直忘了,斯威夫特的任何特征目前都不是一成不变的,有些特征以后可能会被删除。