我有一个有效的代码。
class ListManipulate(val list: List<Char>, val blockCount: Int) {
val result: MutableList<List<Char>> = mutableListOf()
fun permute(sequence: List<Int> = emptyList(), start: Int = 0, count: Int = blockCount) {
if (count == 0) {
result.add(constructSequence(sequence))
return
}
for (i in start .. list.size - count) {
permute(sequence + i, i + 1, count - 1)
}
}
private fun constructSequence(sequence: List<Int>): List<Char> {
var result = emptyList<Char>()
for (i in sequence) {
result += list[i]
}
return result
}
}
然而,当我将result
从MutableList更改为普通List时,即
var result: List<List<Char>> = emptyList()
// ...
result += constructSequence(sequence)
我收到此错误Type mismatch. Require: List<List<Char>>; Found: List<Any>
完整代码如下
class ListManipulate(val list: List<Char>, val blockCount: Int) {
var result: List<List<Char>> = emptyList()
fun permute(sequence: List<Int> = emptyList(), start: Int = 0, count: Int = blockCount) {
if (count == 0) {
result += constructSequence(sequence)
return
}
for (i in start .. list.size - count) {
permute(sequence + i, i + 1, count - 1)
}
}
private fun constructSequence(sequence: List<Int>): List<Char> {
var result = emptyList<Char>()
for (i in sequence) {
result += list[i]
}
return result
}
}
为什么result + constructSequence(sequence)
会导致List<Any>
而不是List<List<Char>>
?
有没有办法我仍然可以使用普通的List&gt;而不是可变列表?
答案 0 :(得分:2)
CTRL +点击IDEA中的+
,您会看到它带您进入以下功能:
/**
* Returns a list containing all elements of the original collection and then all elements of the given [elements] collection.
*/
public operator fun <T> Collection<T>.plus(elements: Iterable<T>): List<T> {
/* ... */
}
这意味着您将elements
的所有单个元素添加到接收器。也就是说,您将所有T
添加到List<List<T>>
。由于List<T>
不是T
,因此您将获得List<Any>
。
答案 1 :(得分:0)
问题在于+=
是overloaded。如果它看到Iterable
,Array
或Sequence
,则表现不同。您必须明确使用plusElement()
来实现您想要的行为。
请考虑以下代码:
class ListManipulate(val list: List<Char>, val blockCount: Int) {
var result: List<List<Char>> = emptyList()
fun permute(sequence: List<Int> = emptyList(), start: Int = 0, count: Int = blockCount) {
if (count == 0) {
result = result.plusElement(constructSequence(sequence))
return
}
for (i in start..list.size - count) {
permute(sequence + i, i + 1, count - 1)
}
}
private fun constructSequence(sequence: List<Int>): List<Char> =
List(sequence.size, { i -> list[sequence[i]] })
}
PS:我也冒昧地将你的constructSequence()
更新为更简洁的内容。
顺便说一句:+=
在内部使用addAll
。
/** * Returns a list containing all elements of the original collection and then all elements of the given [elements] collection. */ public operator fun <T> Collection<T>.plus(elements: Iterable<T>): List<T> { if (elements is Collection) { val result = ArrayList<T>(this.size + elements.size) result.addAll(this) result.addAll(elements) return result } else { val result = ArrayList<T>(this) result.addAll(elements) return result } }
旁注:你也可以这样做:
result.toMutableList().add(constructSequence(sequence))
返回MutableList
很好,唯一的区别是List
接口没有操作方法。在内部,两者都由ArrayList
@SinceKotlin("1.1") @kotlin.internal.InlineOnly public inline fun <T> List(size: Int, init: (index: Int) -> T): List<T> = MutableList(size, init)