如何解构传递给 Kotlin 函数的列表?
我不想将复杂的参数列表传递给函数,而是想传入一个 List 并在函数体中解构它。下面的代码不起作用,所以我恢复到提取每个变量(下面的简化代码示例)-建议?
val (h1, m1, s1, h2, m2, s2) = timeData
将 timeData 解构为组件值集的正确方法是什么?
import java.util.Scanner
const val HOURS = 3600
const val SECONDS = 60
fun secondsBetweenTwoMoments(timeData: List<Int>): Int {
require(timeData.size == 6) { "List must have exactly 6 elements" }
val h1 = timeData[0]
val m1 = timeData[1]
val s1 = timeData[2]
val h2 = timeData[3]
val m2 = timeData[4]
val s2 = timeData[5]
// Convert moment 1 and 2 to seconds
val seconds1 = h1 * HOURS + m1 * SECONDS + s1
val seconds2 = h2 * HOURS + m2 * SECONDS + s2
return seconds2 - seconds1
}
fun main() {
val scanner = Scanner(System.`in`)
val inputs = mutableListOf<Int>()
repeat(6) {
inputs.add(scanner.nextInt())
}
val seconds = secondsBetweenTwoMoments(inputs)
println(seconds)
}
总结一下,“先生,我遇到了一个有趣的魔法……”(咯咯笑)
您只是达到了标准库为 List 定义的解构运算符函数数量的限制。你可以再加一个,然后解构代码就可以工作了:
operator fun <T> List<T>.component6(): T = get(5)
至于为什么他们只构建最多 5 个元素的解构,我认为这是因为除此之外它变得有点脆弱/难以使用,您可能需要考虑使用专门的数据类而不是列表。
我不确定你为什么提到转换,因为你的代码中没有发生转换。
基于@Tenfour04 的回答(谢谢)...这里有两种可能的方法 - 为清楚起见而发布。
引用:
import java.util.Scanner
const val HOURS = 3600
const val SECONDS = 60
operator fun <T> List<T>.component6() = this[5]
operator fun <T> List<T>.component7() = this[6]
fun secondsBetweenTwoMoments(timeData: List<Int>): Int {
val (h1, m1, s1, h2, m2, s2) = timeData
// Convert moment 1 and 2 to seconds
val seconds1 = h1 * HOURS + m1 * SECONDS + s1
val seconds2 = h2 * HOURS + m2 * SECONDS + s2
return seconds2 - seconds1
}
fun secondsBetweenTwoMoments2(timeData1: List<Int>,
timeData2: List<Int> ): Int {
val (h1, m1, s1) = timeData1
val (h2, m2, s2) = timeData2
// Convert moment 1 and 2 to seconds
val seconds1 = h1 * HOURS + m1 * SECONDS + s1
val seconds2 = h2 * HOURS + m2 * SECONDS + s2
return seconds2 - seconds1
}
fun main() {
val scanner = Scanner(System.`in`)
val inputs = mutableListOf<Int>()
repeat(6) {
inputs.add(scanner.nextInt())
}
val seconds = secondsBetweenTwoMoments(inputs)
println(seconds)
val seconds2 = secondsBetweenTwoMoments2(inputs.subList(0,3),
inputs.subList(3,6))
println(seconds2)
}