Kotlin中的Swap函数
除了中描述的java方式外,还有其他更好的方式在kotlin中编写通用交换函数吗Kotlin中的Swap函数,kotlin,Kotlin,除了中描述的java方式外,还有其他更好的方式在kotlin中编写通用交换函数吗 有没有kotlin语言功能可以使通用交换函数更加简洁和直观?kotlin中根本不需要交换函数。您可以使用现有功能,例如: var a = 1 var b = 2 a = b.also { b = a } println(a) // print 2 println(b) // print 1 编辑:谢谢你的评论 我相信交换两个变量的代码足够简单——不必进一步简化它 IMHO最优雅的实施形式是: var a =
有没有kotlin语言功能可以使通用交换函数更加简洁和直观?kotlin中根本不需要交换函数。您可以使用现有功能,例如:
var a = 1
var b = 2
a = b.also { b = a }
println(a) // print 2
println(b) // print 1
编辑:谢谢你的评论
我相信交换两个变量的代码足够简单——不必进一步简化它
IMHO最优雅的实施形式是:
var a = 1
var b = 2
run { val temp = a; a = b; b = temp }
println(a) // print 2
println(b) // print 1
好处:
- 目的是明确的。没有人会误解这一点
将不在范围内temp
- 如果您想编写一些非常可怕的代码,您可以使用如下函数:
inline operator fun <T> T.invoke(dummy: () -> Unit): T {
dummy()
return this
}
请注意,我不建议这样做。只显示它是可能的。Kotlin鼓励在可能的情况下使用不可变数据(例如使用
val
而不是var
)。这大大减少了对细微错误的更改,因为如果值不变,就可以更合理地解释代码
交换两个值在很大程度上与不可变数据相反:我是指交换之前还是之后a
的值
考虑以以下不变的方式重写代码:
val a = 1
val b = 2
val (a2, b2) = b to a
这是通过使用内置的to
扩展功能来实现的,该功能创建了一对对,这是一个很好的用法:
为了使用KotlinList
,您可以创建这种扩展。它返回该列表的一个副本,其中索引a和b处的元素已交换
fun <T> List<T>.swap(a: Int, b: Int): List<T> = this
.toMutableList()
.also {
it[a] = this[b]
it[b] = this[a]
}
fun List.swap(a:Int,b:Int):List=this
.toMutableList()
.还有{
it[a]=这个[b]
it[b]=这个[a]
}
非常简单、快速、优雅的解决方案:
var a = 1
var b = 2
val (b0, a0) = a swap b
a = a0
b = b0
infix fun <A> A.swap(second: A): Pair<A, A> = second to this
var a=1
var b=2
val(b0,a0)=a交换b
a=a0
b=b0
中缀乐趣A.swap(秒:A):Pair=仅次于此
首选a=b。应用{b=a}来交换元素。
如果我们想在lambda内部的变量上执行一些操作,那么选择
a=b.也{someFun(it)}如果使用数组,可以使用以下命令:
fun <T> Array<T>.swap(i: Int, j: Int) {
with(this[i]) {
this@swap[i] = this@swap[j]
this@swap[j] = this
}
}
fun Array.swap(i:Int,j:Int){
(这个[我]){
this@swap[i] =this@swap[j]
this@swap[j] =这个
}
}
如果我试图过多地思考它的实际工作原理(尽管实际上并不复杂),这会让我头疼。当你读到它的时候,它是有意义的!还有一个简单的解释。此语法是a=b的简写形式。另外({b=a})
。我们还看到方法在b
上被调用,参数为lambda{b=a}
也
只需调用其参数,然后返回this
。因此首先执行lambda{b=a}
,然后a
被分配的结果也()
,这就是它的“this”,这是初始的b
。太棒了!它甚至适用于数组元素:a[i]=a[j]。还有{a[j]=a[i]}
@Anton3您的解释是我见过的最好的解释,但我仍然不清楚。你说lambda先被执行。这意味着b被分配了a的值,因此b被覆盖。这里有一些隐式缓冲。我反编译了a=b的字节码,也就是{b=a},在Java中得到了以下结果,这是传统的交换算法:inta=1;int b=2;字节var4=b;b=a;a=var4;那么从概念上讲,b的缓冲在何时何地发生?堆栈Closure?@Phil在Kotlin或Java中,每当参数传递给函数、返回或在闭包中捕获时,都会创建一个副本(对于对象类型,我们会复制一个对GC托管对象的引用)。然而,Kotlin用var
捕获在该系统中打了一个小洞,从概念上讲,捕获是通过将值放在包装器对象中实现的,只要我们有一个对包装器对象的引用,它就允许我们改变内部值(变量名)。这实际上就是他所说的通用Java方式。所以你的答案实际上是“不,没有更好的办法”。我想我倾向于同意。更简洁地说:是的。更直观:。。。也许如果我忘记了我在编程方面学到的一切。:)绝对不是更直观。这是坏代码。我只是在玩。看起来非常可怕!:)函数应该是inline
@Micha人们不再喜欢数组了?
var a = 1
var b = 2
val (b0, a0) = a swap b
a = a0
b = b0
infix fun <A> A.swap(second: A): Pair<A, A> = second to this
fun <T> Array<T>.swap(i: Int, j: Int) {
with(this[i]) {
this@swap[i] = this@swap[j]
this@swap[j] = this
}
}