gpt4 book ai didi

list - 深度复制 2D MutableList 的简洁方法是什么?

转载 作者:行者123 更新时间:2023-12-02 12:48:35 26 4
gpt4 key购买 nike

该元素已经实现了深度复制。

fun <T : DeepCopiable> f(a: MutableList<MutableList<T>>) {
val copied = a.map { it.map { it.deepCopy() }.toMutableList() }.toMutableList()
...
}

我正在使用这种代码,但它看起来很冗长。

最佳答案

由于类型系统的限制,这个问题不能在不绕过类型安全的情况下泛化到单个函数(并且由于 JVM 类型删除,你绝对不想去那个兔子洞当涉及泛型¹)。

但是,您可以编写一个扩展函数来实现深度复制模式,在类型安全的情况下,将维度的每次增加委托(delegate)给前一个函数:

private typealias I<E> = Iterable<E>
private typealias Copy<E> = (E) -> E
private inline fun <T, R> I<T>.mapToMutable(transform: (T) -> R): I<R> = mapTo(mutableListOf(), transform)
fun <E> I<E>.deepCopy1(c: Copy<E>) = mapToMutable { c(it) }
fun <E> I<I<E>>.deepCopy2(c: Copy<E>) = mapToMutable { it.deepCopy1(c) }
fun <E> I<I<I<E>>>.deepCopy3(c: Copy<E>) = mapToMutable { it.deepCopy2(c) }
fun <E> I<I<I<I<E>>>>.deepCopy4(c: Copy<E>) = mapToMutable { it.deepCopy3(c) }
fun <E> I<I<I<I<I<E>>>>>.deepCopy5(c: Copy<E>) = mapToMutable { it.deepCopy4(c) }

由于 JVM 类型删除,函数需要不同的名称(@JVMName 由于类型干扰歧义而无济于事²)。类型别名用于防止水平空间爆炸³,并且函数集通过通用复制函数参数与深度可复制接口(interface)解耦。

示例用法:

fun main(args: Array<String>) {
data class IntHolder(var value: Int)
val original = List(3) { a ->
List(3) { b ->
IntHolder(a + b)
}
}

val copied = original.deepCopy2 { it.copy() }
original[0][0].value = 18258125
println("original=$original")
println("copied =$copied")
}

->

original=[[IntHolder(value=18258125), IntHolder(value=1), IntHolder(value=2)], [IntHolder(value=1), IntHolder(value=2), IntHolder(value=3)], [IntHolder(value=2), IntHolder(value=3), IntHolder(value=4)]]
copied =[[IntHolder(value=0), IntHolder(value=1), IntHolder(value=2)], [IntHolder(value=1), IntHolder(value=2), IntHolder(value=3)], [IntHolder(value=2), IntHolder(value=3), IntHolder(value=4)]]

[1]:因为泛型类型转换是由编译器在运行时执行的,来自 List<Foo> 的转换至 List<Baz>将始终在运行时成功,但稍后在访问强制转换列表时失败。实现上述神奇的“单一功能”是可能的,但最轻微的错误都会导致返回的数据结构在访问时似乎“随机”失败,并出现类转换异常。

[2]:类型为 Iterable<Iterable<Foo>> 的值两者都满足

fun <T> Iterable<T>.baz() (T = Iterable<Foo> ) 和
fun <T> Iterable<Iterable<T>.baz() (T = Foo )

因此,如果链中的所有方法都具有相同的函数名称,但 JVM 名称不同,编译器将无法确定要使用的正确方法。

[3]:

Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<Iterable<ithinkyougetthepoint>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

关于list - 深度复制 2D MutableList 的简洁方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45206241/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com