可以在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项目中,然后向社区提出更改?
答案 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
关键字是编译时功能而不是运行时功能允许它中间表达会产生误导。