是否可以在 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()
调用——但是只为加倍使用一个序列没有什么意义,因为序列开销可能远远高于任何节省。)
我一直在尝试序列编程来处理从 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()
调用——但是只为加倍使用一个序列没有什么意义,因为序列开销可能远远高于任何节省。)