为什么不快速允许三元组中基于let的决策?

时间:2017-06-30 17:36:08

标签: swift

可以在Swift中执行以下操作:

let params: String
if let aString = someOptionalString {
    params = "?someparam=\(aString)"
} else {
    params = ""
}

然而,如果我可以这样写它会更简洁:

let params = let aString = someOptionalString ? "?someparam=\(aString)" : ""

或者

let params = case let aString = someOptionalString ? "?someparam=\(aString)" : ""

然而,这并没有以我能想到的任何方式进行编译。这可能吗?如果没有,为什么不呢?有没有办法建议它实现,或者我只能尝试先将自己添加到Swift项目中,然后向社区提出更改?

2 个答案:

答案 0 :(得分:5)

因为映射可选项是一个更明智的选择:

let params = someOptionalString.map{ "?someparam\($0)" } ?? ""

答案 1 :(得分:1)

要回答您提出的问题,条件let仅适用于if语句或类似的分支结构,在其他任何地方都没有值。

通常情况下,您的模式如下:

if let x = y {
    doSomething(x)
}

...你正在做的是声明一个新的命名空间上下文继承自当前定义x的命名空间;代码是否进入该上下文取决于赋值表达式是否计算为nil。在块之外,x未定义,引用它是错误的。如果您愿意,可以将其视为闭包,可能看起来像:

callIfNotNil(y, {x in doSomething(x)})

当你执行let时,你在当前命名空间中定义它,这意味着它不能在三元运算符的另一侧定义 not ,所以最好的编译器可以给你String!作为一种类型,它会将nil检查推迟到运行时,在很大程度上打败了使用它的点。

原则上,三元可以通过在表达式中间定义一个隐式块来应用相同的行为,但这是程序员混淆的一个秘诀。

至于为什么let x = true; let y = x ? 1 : 2有效但let y = let x = true ? 1 : 2不是有效的,那里存在一些简单的优先级问题,并且let关键字是编译时功能而不是运行时功能允许它中间表达会产生误导。