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

Скажем, что у меня есть путь, проходящий через 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: случайное переопределение Как инициировать массив строк в Котлине? Как получить Kotlin KClass из строки имени класса пакета? Внешняя область Котлина Как настроить задачу processResources в сборке Gradle Kotlin Ошибка Firebase в приложении для Android Обновление Kotlin от 1.0.2 до 1.0.3: java.lang.NoSuchMethodError: виртуальный метод не предоставленInjectedData $ app_compileDebugKotlin () Функции расширения для общих классов в Котлине Как добавить класс Kotlin в проект Android Studio? Spring Data Neo4j 5's EntityScan содержит сопутствующие объекты при использовании Kotlin Использование kotlin с ContentResolver вызвало исключение IllegalArgumentException Vert.x. Как создать реальное приложение многопользовательского JVM? Kotlin Voice Record Upload Overwriting on Firebase Android создает список / объект с информацией, сохраненной из другой активности Kotlin Decompiler генерирует ошибочный код – можно ли предотвратить?