我希望能够有多个let,而下一个let只能使用前一个变量 (如果其不为null)。我想要这个的原因是因为我只想要一个:?所有的让。这可能吗?
关于我希望如何的示例:
fun example() {
firstVariable?.let a -> &&
exampleFunction(a, 3)?.let { a, b ->
// Use a and b freely since they are not null and not optionals
} ?: run {
// Runs if either one of the let is failing
}
}
// a is NOT optional
fun exampleFunction(a: Int, b: Int?): Int? {
if (b == null) {
return null
}
return a + b
}
愚蠢的例子,但是它只是为了显示我的需要...我想检查第一个变量是否为null并运行一个函数,该函数返回带有第一个变量的非可选参数的可选变量-如果有在这些失败中,我想执行其他操作。
我知道如何做到这一点,但我想知道是否有可能或计划做到这一点? (在Swift中是可能的)。
如何在Swift中做到这一点:
// First check a, then use a in the same expression if its validated
if let a = firstVariable,
let b = exampleFunction(a) {
// Use a and b as non-optionals
} else {
// a or b failed
}
答案 0 :(得分:1)
您可以从Kotlin上受益,并为您的案例编写扩展功能。 vararg
,因为我们不知道要传递多少变量,然后检查所有变量是否都不为null,如果不是,则返回所有变量。如果任何变量为null,则什么都不会发生。
fun <T: Any> multipleLetCheck(vararg variables: T?, block: (List<T>) -> Unit): Unit? {
return if (variables.all { variable -> variable != null }) {
block(variables.filterNotNull())
} else {
null
}
}
// usage
multipleLetCheck(firstVariable, 3){ (firstVariable, secondVariable) ->
// work with firstVariable and secondVariable
} ?: run {
}
答案 1 :(得分:1)
您可能会误解了let
的工作方式。我要解释一下。简而言之,在kotlin中无法实现所需的行为,或者至少您不能在没有任何缺点的情况下习惯地模仿它。
我不知道很快,但似乎let
所使用的语言本身提供了某种语法构造。它使您可以定义具有某些 local 范围的变量,并且可以将其链接(例如短路&&
)。
但是在Kotlin中,let
只是一个正常功能。
请参见documentation。基本上无非是
fun <T, R> T.let(block: (T) -> R): R = block(this)
它允许将具有普通参数的函数作为带有receiver type的函数来调用。
实际的null检查是通过?.
运算符完成的。
它接受一个可选/可为空的值作为左侧操作数,或者短路返回空值,或者在右侧使用非空左侧作为接收器类型调用该函数。 let
只是在此处调用的一种可能函数。
相似的?:
运算符采用可选的/可为空的LHS操作数,如果该值不为null或在RHS上计算表达式,则返回该值。
定义这些变量的一种方法是嵌套let
:
firstVariable?.let{a -> exampleFunction(a, 3)?.let{b -> a + b}} ?: run{}
其中a + b
仅是同时使用两个值的示例。但是,如果长度超过一行,这将变得不便。如果仍要定义局部变量,则可以使用run
创建一个块,并在?:
的右侧使用跳转语句
run {
val a = firstValue ?: return@run null
val b = exampleFunction(a, 3) ?: return@run null
return@run a + b
} ?: run{}
虽然上述代码在所有return@run null
替换中看起来都很丑陋,但是可能有一些方法可以减少重复代码的数量,例如通过使用匿名函数(摆脱@run
部分)或返回Unit
并通过一些副作用操作来保护最后一个值。 (以摆脱null
和最后一个return语句)