翻译说明:
原标题: One Line Swap in Kotlin
原文地址: One Line Swap in Kotlin
原文作者: Vibhanshu Sharma
原文翻译
Kotlin中添加了很多有用的语法糖,帮我们省去了以往在java中需要写很多模版代码的功夫。交换两个变量就是一个例子:
最简单的交换方法需要创建一个临时变量和三行代码:
var temp = a
a = b
b = temp
如果用Kotlin的话我们就不需要创建临时变量(译者注:实际上还是创建了),代码也只需要一行:
secondVar = firstVar.apply { firstVar = secondVar }
或者:
secondVar = firstVar.also { firstVar = secondVar }
下面我们来解释,上面两段代码到底是怎么运作的:
作用域函数,比如apply和also这两个,在使用的时候会给所要作用的变量在给定的lambda表达式中创建临时的作用域。
Also和apply均会返回他们所作用的对象本身,所以当我们用firstVar调用apply或者also的时候,首先会创建一个临时作用域,在这个作用域中我们能够直接或间接地调用firstVar所指向的对象,我们在lambda中重新使它指向secondVar所指向的对象。
然后,secondVar被赋值了在这个作用域中能够访问到的那个对象,也就是以前firstVar所指向的对象。
fun main() {
var firstVar= 5
var secondVar=6
// 交换 a 和 b
secondVar = firstVar.apply{firstVar = secondVar}
// 用also也成
print(firstVar) // prints 6
print(secondVar) // prints 5
}
如果想了解更多关于作用域函数的知识,可以看官网:
译者注
很有意思的一个例子,但是作者解释的不够详细,上面这个例子可以用kotlin转换Java代码解释的更详细一点。
fun main() {
var firstVar = 5
var secondVar = 6
secondVar = firstVar.also {
firstVar = secondVar
}
print(firstVar == secondVar) // prints 6
print(secondVar) // prints 5
}
转译出来代码如下:
public final class TestClassKt {
public static final void main() {
int firstVar = 5;
int secondVar = 6;
byte var2 = firstVar;
boolean var3 = false;
boolean var4 = false;
int var6 = false;
firstVar = secondVar;
Unit var7 = Unit.INSTANCE;
secondVar = var2;
boolean var8 = firstVar == var2;
var3 = false;
System.out.print(var8);
var3 = false;
System.out.print(secondVar);
}
...
}
所以说简单来讲就是作用域函数所涉及的上下文对象(Context object)指的是对象本身,而不是它的引用,在作用域函数中的lambda表达式中交换变量,firstVar = secondVar,仅仅改变了引用所指向的对象,并没有改变对象本身,同时也没有改变作用域函数本身的上下文对象。这可能是个值得注意的点。
还有一点是为什么转移出来的Java代码中没有lambda表达式的踪迹,是因为作用域函数都是inline修饰的,使用inline修饰的高阶函数会平铺开lambda表达式,提升执行效率,具体可见: