Kotlin和详细的数组实例化
假设我有通过4个顶点的路径。 在做快速原型时,我会在java中定义这个
double[][] path = {{1.0, 2.0}, {1.0,3.0}, {3.0,4.0}, {8.0,9.0}}
使用arrayOf和doubleArrayOf函数,Kotlin中的代码将会是相同的
val path = arrayOf(doubleArrayOf(1.0, 2.0), doubleArrayOf(1.0, 2.0), doubleArrayOf(1.0,3.0), doubleArrayOf(8.0,9.0))
这感觉有点冗长。 有没有解决这个问题的Kotlin方法?
编辑:用例是在数字数据的“REPL like”环境中回答查询,例如Matlab或SciPy。
arrayOf
和doubleArrayOf
以及其他类似于stdlib的顶级函数。 为了缩短语法,您可以轻松地创建自己的函数,其范围在顶层,在类中,甚至在本地函数中:
通过创建:
fun pathOf(vararg points: DoubleArray): Array = points fun pt(x: Double, y: Double) = doubleArrayOf(x,y)
这允许:
val path = pathOf(pt(1.0, 2.0), pt(1.0, 2.0), pt(1.0, 3.0), pt(8.0, 9.0))
现在给出嵌套数组意味着未来的读者或代码。 将functionpoint
命名为pt
, xy
或任何适合您的用例。
这个代码只比原来的稍长一点,比Java更可读/有意义:
double[][] path = {{1.0, 2.0}, {1.0, 3.0}, {3.0, 4.0}, {8.0, 9.0}}
这些函数与使用arrayOf
和doubleArrayOf
一样有效,如果重复使用,JVM将最终inline
它们,但是如果您紧张,可以让它们自己inline
。
Kotlin的意图是扩展 ,任何时候遇到像这样的问题想想如何扩展一个API或改变一个函数来获得你想要的可读性。
就stdlib而言,这个时间短得可以。 你可以自己定义一个辅助函数:
fun doubles(vararg values: Pair) = values .map { doubleArrayOf(it.first, it.second) } .toTypedArray()
用法:
fun main(args: Array) { val path = doubles(1.0 to 2.0, 1.0 to 3.0, 3.0 to 4.0, 8.0 to 9.0) }
这不是最有效的解决方案,因为它涉及到一个临时数组和列表的装箱和分配,但是如果你只是原型,这应该没问题。
编辑:
我也做了一个版本,你可以添加任意长度的数组:
inline fun doubles(block: DoubleArrayBuilder.() -> Unit) = DoubleArrayBuilder() .apply(block) .list.toTypedArray() class DoubleArrayBuilder { val list = mutableListOf() fun add(vararg doubles: Double) = list.add(doubles) }
用法:
fun main(args: Array) { val path = doubles { add(2.0, 3.0, 4.0) add(2.0, 3.0, 4.0) add(2.0, 3.0, 4.0) } }