。
ただし、タイプセーフの問題では、ディメンション内のすべての増加のために前の関数に委譲、深い・コピー・パターンを実装する拡張機能のチェーンを書き込むことができます。
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
はタイプ干渉のあいまい性のために助けになりません)。タイプエイリアスは水平方向の爆発を防止するために使用され、機能セットは一般的なコピー機能パラメータを介してディープコピー可能なインターフェイスから切り離されます。
使用例:
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<Baz>
からList<Foo>
からキャストは常に、実行時にコンパイラによってでしょう実行されるため実行時には成功しますが、キャストされたリストにアクセスすると後で失敗します。前述の魔法の「単一機能」を実装することは可能ですが、わずかなエラーはクラスキャスト例外を使ってアクセスすると一見 "ランダム"にならない戻りデータ構造になります。
[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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
書く 'fは(a)の'のためのあなたのコピー動作が行うなし非常に冗長に見えます。 –
@IngoKegelの意見では、インタフェースメソッドの名前がわずかに異なる場合、コードの目的(ディープコピー)はすぐには分かりません。 –