一般交换值简单办法是:
var a = 1
var b = 2
val temp = a
a = b
b = temp
声明一个中间变量的方式
一坤年前参阅kotlin文档看到一个交换值例子:
var a = 1
var b = 2
a = b.also { b = a }
println("a:$a , b:$b“)
输出a:2 , b: 1 成功交换了值,换成apply也可以。
一坤年后点开了also的源码:
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
contract 是个契约函数是告诉编译器block函数只执行一次,后面的block(this)执行闭包里面的代码a赋值给了b,然后返回b赋值给a,感觉很费解,那这样不是a、b都是1了吗,怎么进行的转换呢。
那就看下编译器做了什么优化嘛,查看编译生成的java代码:
int a = 1;
int b = 2;
int var6 = false;
Unit var23 = Unit.INSTANCE;
String var4 = "-->>a" + b + ",b" + a;
System.out.println(var4);
好家伙,这里编译器直接让输出对调了a、b的值。而且这里int var6 = false又是什么鬼,android sutdio的bug吗?
这里应该是字节码比java代码能表示的东西广,有的字节码本来就不能直接翻译成准确的java代码。
而这里a、b没有使用,编译器懒得交换,优化的真棒[狗头],那就随便使用一下:
var a = 1
var b = 2
a = b.also { b = a }
val c = a.toString().plus("is a")
println("-->>a$a,b$b")
生成的java代码:
int a = 1;
int b = 2;
byte var4 = b;
int var6 = false;
b = a;
Unit var24 = Unit.INSTANCE;
a = var4;
String c = var4 + "is a";
String var5 = "-->>a" + a + ",b" + b;
编译器生成了中间变量var4来转换值,好了,舒服了。
ps:感谢请教过的各位巨佬