是否可以在 Kotlin 中使用 vararg 实现序列编程?

Is it possible to implement sequence programming with vararg in Kotlin?

我一直在尝试序列编程来处理从 vararg 参数中获得的数据。我想将列表中的每个数字相乘并将其添加到新的数组列表中。是否可以使用序列

我附上下面的代码:

fun main() {
    val number = asList(10, 20, 30, 40, 50)
    print(number)
}

fun <T> asList(vararg input: T): List<T> {
    val result = ArrayList<T>()
    input.map {it * 2}.foreach(result.add(it))
    return result
}

这是我得到的错误: enter image description here

是的,可以从可变参数创建序列;我稍后再讲。

首先,上面代码中的主要问题是,不幸的是,它不能通用地完成。你得到的错误是因为 T 可以是任何类型,并且大多数类型不能相乘,所以编译器告诉你你不能做 * 2.

您可能会考虑将 T 限制为 Number 的子类,但这没有帮助。 (Number 是一个非常弱的类型;它不允许您进行任何算术运算,可能是因为您无法判断结果必须是什么类型,也不知道可能会发生什么舍入或溢出。做的是将值转换为特定类型。)

但是如果您删除类型参数并将其编码为特定的数字类型,例如 Int,那么它可以正常工作。

foreach 调用的代码中也存在拼写和语法错误。修复这些也会给出例如:

fun asList(vararg input: Int): List<Int> {
    val result = ArrayList<Int>()
    input.map{ it * 2 }.forEach{ result.add(it) }
    return result
}

不过,这会做很多不必要的工作; map() 已经是 returns 一个列表,因此创建第二个列表并逐个元素复制到其中没有意义!此外,名称具有误导性。所以它可能只是:

fun asListDoubled(vararg input: Int) = input.map{ it * 2 }

你的问题提到了序列;但是您的代码使用普通的急切列表。如果你想要一个延迟计算的序列,你可以只添加一个 asSequence() 调用,例如:

fun asSequenceDoubled(vararg input: Int) = input.asSequence().map{ it * 2 }

但请注意,这现在 returns 是 Sequence<Int>,而不是 List<Int>,因此您可以继续对它进行进一步的惰性操作。 (如果你想要一个 List<Int>,那么你可以只附加一个 toList() 调用——但是只为加倍使用一个序列没有什么意义,因为序列开销可能远远高于任何节省。)