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。

arrayOfdoubleArrayOf和其他类似的,只是stdlib中的顶级函数。 为了缩短语法,您可以轻松地创建自己的函数,其范围在顶层,在类中,甚至在本地函数中:

通过创建:

 fun pathOf(vararg points: DoubleArray): Array<out DoubleArray> = 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)) 

现在给出嵌套数组意味着未来的读者或代码。 将功能point命名为ptxy或任何适合您的用例。

这个代码只比原来的稍长一点,比Java更可读/有意义:

 double[][] path = {{1.0, 2.0}, {1.0, 3.0}, {3.0, 4.0}, {8.0, 9.0}} 

这些函数与使用arrayOfdoubleArrayOf一样有效,如果重复使用,JVM将最终inline它们,但是如果您紧张,可以让它们自己inline

Kotlin的意图是扩展 ,任何时候遇到像这样的问题想想如何扩展一个API或改变一个函数来获得你想要的可读性。

就stdlib而言,这个时间短得可以。 你可以自己定义一个辅助函数:

 fun doubles(vararg values: Pair<Double, Double>) = values .map { doubleArrayOf(it.first, it.second) } .toTypedArray() 

用法:

 fun main(args: Array<String>) { 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<DoubleArray>() fun add(vararg doubles: Double) = list.add(doubles) } 

用法:

 fun main(args: Array<String>) { val path = doubles { add(2.0, 3.0, 4.0) add(2.0, 3.0, 4.0) add(2.0, 3.0, 4.0) } }