Котлин и подробный экземпляр массива

Скажем, что у меня есть путь, проходящий через 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)) 

Это выглядит немного многословным. Есть ли способ Котлина решить это?

Изменить: прецедент – это ответ на запросы в среде «REPL like» на числовые данные, то есть подумайте о Matlab или SciPy.

arrayOf и doubleArrayOf и другие подобные им, являются только функциями верхнего уровня в 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 , 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 goest, это как можно меньше. Однако вы могли бы определить вспомогательную функцию:

 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) } } 
Intereting Posts
Kotlin \ Java – Строка типа "$ 1" на номер Pass facebook AccessToken by Retrofit Строка Kotlin String to Int Kotlin Vertx Тип Несоответствие найдено Future <Unit> ожидаемый обработчик <AsyncResult <Void >> Тестирование AnkoComponents и насмешка AnkoContext kotlin для переопределения типов protobuf toString ClassCastException с использованием метода bindService ServiceTestRule Блок Try-Catch недоступен? Имеет ли внутренний блок try-finally внешний блок try-catch недоступен? пусть, также, применять, takeIf, takeUnless в Котлине Как Kotlin возьмет val как ключевое слово из класса java Android OutOfMemoryError: не удалось выделить выделение байтов 57993496 с 16764448 бесплатными байтами Kotlin: преобразовать большой список в подсписку заданного размера раздела Статические переменные в Котлине по-прежнему являются частью экземпляров объектов Как компилировать Kotlin для включения jar Java с командной строкой? Ошибка компиляции в Eclipse в проекте Kotlin + Java, но проект строится с Maven