(译)Kotlin中用一行代码交换变量

1,394 阅读2分钟

翻译说明:

原标题: 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 }

下面我们来解释,上面两段代码到底是怎么运作的:

作用域函数,比如applyalso这两个,在使用的时候会给所要作用的变量在给定的lambda表达式中创建临时的作用域。

Alsoapply均会返回他们所作用的对象本身,所以当我们用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 

}

如果想了解更多关于作用域函数的知识,可以看官网:

kotlinlang.org/docs/scope-…

译者注

很有意思的一个例子,但是作者解释的不够详细,上面这个例子可以用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表达式,提升执行效率,具体可见:

blog.kotlin-academy.com/effective-k…