我怎样才能在Kotlin中获得Python的切片运算符?

Python有一个切片运算符,我希望它在Kotlin。

我想在Kotlin下面的代码

val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) println( list[5] ) println( list[2, 5].joinToString() ) println( list[2, 10, 2].joinToString() ) val mutableList = mutableListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) mutableList[2, 10, 2] = listOf(1, 2, 3, 4) println( mutableList.joinToString() ) 

输出以下内容:

 6 3, 4, 5 3, 5, 7, 9 1, 2, 1, 4, 2, 6, 3, 8, 4, 10 

但它不工作!

这可以使用扩展函数和操作符重载来完成。 以下代码将解决您提供的问题。 经过一些调整,它将处理Python提供的所有其他选项。

 operator fun <T : Any> Iterable<T>.get(start: Int, end: Int, step: Int = 1): Iterable<T> { check(start < end) check(step > 0) val iterator = iterator() var s = 0 return generateSequence { while (s < start && iterator.hasNext()) { iterator.next() s++ } if (iterator.hasNext()) { if (s < end) { val value = iterator.next() repeat(step - 1) { s++; if (iterator.hasNext()) iterator.next() } s++ value } else { null } } else { null } }.asIterable<T>() } operator fun <T : Any> MutableList<T>.set(start: Int, end: Int, step: Int = 1, newElts: Iterable<T>) { check(start < end) check(step > 0) val iterator = iterator() val newIterator = newElts.iterator() var s = 0 while (s < start && iterator.hasNext()) { iterator.next() s++ } while (iterator.hasNext()) { if (s < end) { if (newIterator.hasNext()) { this[s] = newIterator.next() iterator.next() repeat(step - 1) { s++; if (iterator.hasNext()) iterator.next() else return } s++ } else return } } } 

reddit上reddit提出了另一种解决方案,不使用Python的语法,但我很喜欢。

 operator fun <T: Any> Iterable<T>.get(range: IntProgression) = asSequence().run { range.mapNotNull { index -> elementAtOrNull(index) } } operator fun <T: Any> MutableList<T>.set(range: ClosedRange<Int>, from: Iterable<T>) { for (i in range.start..minOf(range.endInclusive, size - 1)) removeAt(range.start) addAll(range.start, from.toList()) } @Test fun slice() { val list = mutableListOf(5, 6, 7, 8, 9, 10) assertEquals(listOf(7, 8, 9), list[2..4]) assertEquals(listOf(10, 8), list[5 downTo 2 step 2]) list[2..4] = listOf(77) assertEquals(listOf(5, 6, 77, 10), list) list[0..10] = listOf(1, 2, 3) assertEquals(listOf(1, 2, 3), list) }