seocod.ru http://seocod.ru/forum/ |
|
код Kotlin & Java http://seocod.ru/forum/viewtopic.php?f=31&t=5295 |
Страница 2 из 3 |
Автор: | Olej [ 02 июн 2017, 17:45 ] |
Заголовок сообщения: | Re: код Kotlin & Java |
Olej писал(а): После трансформации оба файла, и Complex.kt (который был мной взят где-то из публичной библиотеки в Интернет) и poly.kt (который написан под задачу) содержат синтаксические ошибки (с точки зрения семантики Kotlin). Ошибки в poly.kt как-то связаны с конструктором Double, который "определён в kotlin.Double" и, нужно думать, отличается от определений в Java. Это, насколько я понял, связано с тем, что в преобразованных выражениях по типу: Код: val x = Double(st.nextElement() as String).toDouble() ... здесь Double совпадает по написанию с базовым типом Kotlin, а в исходном коде имелась в виду Java обёртка Double для примитивного типа JVM double. Теперь тип для x должен бы быть Double? ... Со всем этим буду разбираться по (переводу) документации Kotlin здесь: Основные типы. |
Автор: | Olej [ 02 июн 2017, 19:26 ] | ||
Заголовок сообщения: | Re: код Kotlin & Java | ||
Olej писал(а): ... здесь Double совпадает по написанию с базовым типом Kotlin, а в исходном коде имелась в виду Java обёртка Double для примитивного типа JVM double. Теперь тип для x должен бы быть Double? ... Со всем этим буду разбираться по (переводу) документации Kotlin здесь: Основные типы. Удалось это победить, заменив показанные комментированные строки но новые не комментированные: Код: // val x = Double(st.nextElement() as String).toDouble() val x: Double? = (st.nextElement() as String).toDouble() // val y = Double(st.nextElement() as String).toDouble() val y: Double? = (st.nextElement() as String).toDouble() // polygon.add(Complex(x, y)) polygon.add(Complex(x!!, y!!)) Читаем о всём этом здесь: Nullable типы и Non-Null типы: - меняем типы x & y на Nullable Double? (обёртка Java Double); - но трансформация Complex определила конструктор как: Код: /** * Create a complex number initially equal to x + iy */ constructor(x: Double, y: Double) { re = x //.toDouble() im = y //.toDouble() } - он требует Non-Null и не допустит Nullable тип Double? - не желая менять автоматически сгенерированный класс Complex ... - используем оператор !! (описано там же): Код: polygon.add(Complex(x!!, y!!)) Теперь всё компилируется и успешно выполняется ... аналогично исходному приложению на Java!
|
Автор: | Olej [ 02 июн 2017, 20:07 ] | |||
Заголовок сообщения: | Re: код Kotlin & Java | |||
Olej писал(а): Теперь всё компилируется и успешно выполняется ... аналогично исходному приложению на Java! При запуске (Run) собранного в IDEA проекта, там печатается полная строка запуска (скопируем)... В каталоге собранного проекта: Код: [olej@dell triangle]$ pwd /home/olej/IdeaProjects/triangle/out/production/triangle [olej@dell triangle]$ ls Complex.class Complex$Companion.class poly.class Polygon.class Это собранные IDEA .class для JVM. Из этого каталога $HOME/IdeaProjects/$PROECT/out/production/$PROECT запускаю в терминале приложение в JVM: Код: [olej@dell triangle]$ /usr/lib/jvm/java-1.8.0-openjdk/bin/java -javaagent:/home/olej/idea-IC-171.4424.56/lib/idea_rt.jar=42979:/home/olej/idea-IC-171.4424.56/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/charsets.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/jaccess.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/jce.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/jsse.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/management-agent.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/resources.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/rt.jar:/home/olej/IdeaProjects/triangle/out/production/triangle:/home/olej/.IdeaIC2017.1/config/plugins/Kotlin/kotlinc/lib/kotlin-runtime.jar:/home/olej/.IdeaIC2017.1/config/plugins/Kotlin/kotlinc/lib/kotlin-reflect.jar poly координаты вершин в формате: X Y вершина № 1 : 0 0 вершина № 2 : 0 1 вершина № 3 : 1 0 вершина № 4 : вершин 3 : [0.0,0.0] [0.0,1.0] [1.0,0.0] периметр = 3.414213562373095 площадь = 0.5 --------------------------------- координаты вершин в формате: X Y вершина № 1 : завершение работы Вот это и есть готовое приложение!
|
Автор: | Olej [ 02 июн 2017, 20:16 ] |
Заголовок сообщения: | Re: код Kotlin & Java |
Olej писал(а): Код: [olej@dell triangle]$ /usr/lib/jvm/java-1.8.0-openjdk/bin/java -javaagent:/home/olej/idea-IC-171.4424.56/lib/idea_rt.jar=42979:/home/olej/idea-IC-171.4424.56/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/charsets.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/jaccess.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/jce.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/jsse.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/management-agent.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/resources.jar:/usr/lib/jvm/java-1.8.0-openjdk/jre/lib/rt.jar:/home/olej/IdeaProjects/triangle/out/production/triangle:/home/olej/.IdeaIC2017.1/config/plugins/Kotlin/kotlinc/lib/kotlin-runtime.jar:/home/olej/.IdeaIC2017.1/config/plugins/Kotlin/kotlinc/lib/kotlin-reflect.jar poly Вот это и есть готовое приложение! Сотрудники компании JetBrains (разработчика) подсказали: Цитата: всё, что начинается с /usr/lib/jvm/java-1.8.0-openjdk/, можно пропустить Код: [olej@dell triangle]$ java -javaagent:/home/olej/idea-IC-171.4424.56/lib/idea_rt.jar=42979:/home/olej/idea-IC-171.4424.56/bin -Dfile.encoding=UTF-8 -classpath /home/olej/IdeaProjects/triangle/out/production/triangle:/home/olej/.IdeaIC2017.1/config/plugins/Kotlin/kotlinc/lib/kotlin-runtime.jar poly
координаты вершин в формате: X Y вершина № 1 : завершение работы |
Автор: | Olej [ 02 июн 2017, 21:00 ] |
Заголовок сообщения: | Re: код Kotlin & Java |
Теперь сравним эквиваленты (более того, сгенерированные автоматически!) кода на Java и кода на Kotlin, выполняющиеся на одной и той же Java виртуальной языковой машине JVM (сами файлы прикреплены к сообщениям ранее): - poly.java (было): Код: import java.io.*; import java.util.*; import java.lang.Double.*; class Polygon extends ArrayList<Complex> { // class Complex заимствуется из отдельного файла public String toString() { String ret = ""; for( int i = 0; i < size(); i++ ) ret += "[" + ( new Double( get( i ).re ) ).toString() + "," + ( new Double( get( i ).im ) ).toString() + "] "; return ret; } public double perimeter() { double summa = 0.0; for( int i = 0; i < size(); i++ ) summa += get( i ).minus( i != size() - 1 ? get( i + 1 ) : get( 0 ) ).r(); return summa; } public double square() { double summa = 0.0; for( int i = 1; i < size() - 1; i++ ) { Complex side1 = get( i ).minus( get( 0 ) ), side2 = get( i + 1 ).minus( get( 0 ) ); summa += side1.r() * side2.r() * Math.abs( Math.sin( side1.theta() - side2.theta() ) ) / 2.; } return summa; } } public class poly { public static void main( String[] args ) { Scanner in = new Scanner( System.in ); // создание объекта чтения из стандартного потока ввода while( true ) { System.out.println( "координаты вершин в формате: X Y" ); Polygon polygon = new Polygon(); String coord = ""; while( true ) { System.out.printf( "%s%d%s", "вершина № ", polygon.size() + 1, " : " ); try { coord = in.nextLine(); } // чтение строки из консоли catch( java.util.NoSuchElementException ex ) { System.out.println( "завершение работы" ); System.exit( 0 ); // EOF: ^D } if( 0 == coord.length() ) if( polygon.size() != 0 ) break; // завершение многоугольника else { System.out.println( "завершение работы" ); System.exit( 0 ); } try { // выделение координат StringTokenizer st = new StringTokenizer( coord, " \t\n" ); double x = ( new Double( (String)st.nextElement() ) ).doubleValue(), y = ( new Double( (String)st.nextElement() ) ).doubleValue(); polygon.add( new Complex( x, y ) ); } catch( java.util.NoSuchElementException ex ) { System.out.println( "ошибка ввода!: " + ex.toString() ); continue; } catch( java.lang.NumberFormatException ex ) { System.out.println( "ошибка формата!: " + ex.toString() ); continue; } } System.out.println( "вершин " + polygon.size() + " : " + polygon ); System.out.println( "периметр = " + polygon.perimeter() ); System.out.println( "площадь = " + polygon.square() ); System.out.println( "---------------------------------" ); } } } - poly.kt (стало): Код: import java.io.*
import java.util.* import java.lang.Double.* internal class Polygon : ArrayList<Complex>() { // class Complex заимствуется из отдельного файла override fun toString(): String { var ret = "" for (i in 0..size - 1) ret += "[" + get(i).re.toString() + "," + get(i).im.toString() + "] " return ret } fun perimeter(): Double { var summa = 0.0 for (i in 0..size - 1) summa += get(i).minus(if (i != size - 1) get(i + 1) else get(0)).r() return summa } fun square(): Double { var summa = 0.0 for (i in 1..size - 1 - 1) { val side1 = get(i).minus(get(0)) val side2 = get(i + 1).minus(get(0)) summa += side1.r() * side2.r() * Math.abs(Math.sin(side1.theta() - side2.theta())) / 2.0 } return summa } } object poly { @JvmStatic fun main(args: Array<String>) { val `in` = Scanner(System.`in`) // создание объекта чтения из стандартного потока ввода while (true) { println("координаты вершин в формате: X Y") val polygon = Polygon() var coord = "" while (true) { System.out.printf("%s%d%s", "вершина № ", polygon.size + 1, " : ") try { coord = `in`.nextLine() } // чтение строки из консоли catch (ex: java.util.NoSuchElementException) { println("завершение работы") System.exit(0) // EOF: ^D } if (0 == coord.length) if (polygon.size != 0) break // завершение многоугольника else { println("завершение работы") System.exit(0) } try { // выделение координат val st = StringTokenizer(coord, " \t\n") val x: Double? = (st.nextElement() as String).toDouble() val y: Double? = (st.nextElement() as String).toDouble() polygon.add(Complex(x!!, y!!)) } catch (ex: java.util.NoSuchElementException) { println("ошибка ввода!: " + ex.toString()) continue } catch (ex: java.lang.NumberFormatException) { println("ошибка формата!: " + ex.toString()) continue } } println("вершин " + polygon.size + " : " + polygon) println("периметр = " + polygon.perimeter()) println("площадь = " + polygon.square()) println("---------------------------------") } } } |
Автор: | Olej [ 02 июн 2017, 21:09 ] |
Заголовок сообщения: | Re: код Kotlin & Java |
Olej писал(а): Теперь сравним эквиваленты Это практически "подстрочный" перевод ![]() Код: [olej@dell triangle.java]$ wc -l poly.java 75 poly.java [olej@dell triangle]$ wc -l poly.kt 79 poly.kt Но! - это механический перевод (посмотрели как это делается)... Тем не менее: - в Kotlin есть целый ряд конструкций высокого уровня, которых нет в Java и близко... - но не это даже главное - Kotlin спроектирован для надёжного контроля объектов Nullable типов, не имеющих возможности возбуждать NullPointerException исключение! |
Автор: | Olej [ 02 июн 2017, 23:07 ] | ||
Заголовок сообщения: | Re: код Kotlin & Java | ||
Olej писал(а): - в Kotlin есть целый ряд конструкций высокого уровня, которых нет в Java и близко... Дальше меня интересует именно тестирование таких конструкций ... по крайней мере, самых интересных. Описания синтаксиса/семантики черпаем здесь: Reference - оригинальная документация Руководство по языку Kotlin - перевод этой документации Но прежде разбираемся с терминальной (CLI) сборкой. На примере простейшей программы: Код: fun main(args: Array<String>) { println("Hello, World!") } Потому что: - мне совершенно нет нужды в могучей среде IDEA для простейших тестов ... хотелось бы использовать простейшую терминальную сборку; - привязка инструмента (в данном случае языка Kotlin) к реализации (в данном случае среда разработки IDEA) - плохая идея, и здесь как-раз случай проверить что это не так; Варианты сборки (и запуска), они мне все пригодятся ![]() 1. То, что описано в README - сборка всего в архив jar: Код: [olej@dell tests]$ kotlinc test_fun.kt -include-runtime -d test_fun.jar [olej@dell tests]$ java -jar test_fun.jar Hello, World! [olej@dell tests]$ ls -l test_fun.jar -rw-rw-r-- 1 olej olej 865731 июн 2 23:14 test_fun.jar 2. Сборка в .class : Код: [olej@dell tests]$ kotlinc test_fun.kt -include-runtime -d xxx [olej@dell tests]$ tree xxx xxx ├── META-INF │ └── main.kotlin_module └── Test_funKt.class 1 directory, 2 files [olej@dell tests]$ ls -l xxx/Test_funKt.class -rw-rw-r-- 1 olej olej 972 июн 2 22:35 xxx/Test_funKt.class Обратите внимание на размер! Но при этом гораздо усложняется запуск приложения: Код: [olej@dell tests]$ which kotlinc ~/.sdkman/candidates/kotlin/current/bin/kotlinc [olej@dell kotlin]$ ls -l ~/.sdkman/candidates/kotlin/ итого 4 drwxr-xr-x 1 olej olej 44 апр 27 19:33 1.1.2-2 lrwxrwxrwx 1 olej olej 44 май 25 12:31 current -> /home/olej/.sdkman/candidates/kotlin/1.1.2-2 Код: [olej@dell tests]$ pwd /home/olej/2017_WORK/own.WORK/Kotlin/tests [olej@dell tests]$ java -classpath $HOME/.sdkman/candidates/kotlin/1.1.2-2/lib/kotlin-runner.jar:xxx Test_funKt Hello, World! Или так: Код: [olej@dell tests]$ cd xxx
[olej@dell xxx]$ pwd /home/olej/2017_WORK/own.WORK/Kotlin/tests/xxx [olej@dell xxx]$ java -classpath $HOME/.sdkman/candidates/kotlin/1.1.2-2/lib/kotlin-runner.jar:./ Test_funKt Hello, World!
|
Автор: | Olej [ 02 июн 2017, 23:29 ] |
Заголовок сообщения: | Re: код Kotlin & Java |
Olej писал(а): На примере простейшей программы: Код: fun main(args: Array<String>) { println("Hello, World!") } Здесь уже вылезает радикальное отличие от Java - функции Kotlin могут быть вне класса! Стартовую функцию main() не нужно как статический метод заворачивать в фиктивный класс. Т.е. доведенная до абсурда объектность Java здесь ослаблена. |
Автор: | Olej [ 03 июн 2017, 13:28 ] | ||
Заголовок сообщения: | Re: код Kotlin & Java | ||
Olej писал(а): Olej писал(а): - в Kotlin есть целый ряд конструкций высокого уровня, которых нет в Java и близко... Дальше меня интересует именно тестирование таких конструкций ... по крайней мере, самых интересных. Тестирую функции (и функции-методы), как наиболее сильно отличающуюся часть... Но для начала сделаю тестовое приложение, в которое я смогу в произвольном количестве дописывать тестируемые функции (или фрагменты кода). Вот как-то так: Код: import java.lang.Math.* import java.util.Scanner.* fun tg( x: Double ): Double = sin( x ) / cos( x ); // функция - одиночное выражение fun test1(): Unit { printHello( "Kotlin" ) printHello( null ) // `return Unit` или `return` необязательны } fun printHello(name: String?): Unit { if (name != null) println("Hello ${name}") else println("Hi there!") } fun main( args: Array<String> ) { val tests: Array< ()->Unit > = arrayOf( { println( tg( 1.0 ) ); }, { test1() } ) if(args.size == 0) for (f in tests) f() else for (i in args.indices) { try { val x = args[i].toInt() if(x <= 0 || x > tests.size) { println("ошибка размера!: " + args[i]) continue } println( x.toString() + " ------------------------------------------" ) tests[ x - 1 ]() } catch (ex: java.lang.NumberFormatException) { println("ошибка формата!: " + args[i]) } } } Это компилируется и выполняется так: Код: [olej@dell tests]$ make test_fun.jar kotlinc test_fun.kt -include-runtime -d test_fun.jar [olej@dell tests]$ java -jar test_fun.jar 0 1 2 ошибка размера!: 0 1 ------------------------------------------ 1.557407724654902 2 ------------------------------------------ Hello Kotlin Hi there! [olej@dell tests]$ java -jar test_fun.jar 1.557407724654902 Hello Kotlin Hi there! - если запуск без параметров - последовательно выполняются все тесты из массива функций tests - если запуск с числовыми порядковыми номерами тестов - выполняются только эти тесты - если параметр не число или выходит за пределы наличествующих тестов - диагностируется ошибка Дальше это даст мне возможность, при тестировании какой-то возможности функций, показывать только код этой функции (вставленной в массив tests) + результат её выполнения... а не тянуть весь накопленный код для всех тестов.
|
Автор: | Olej [ 03 июн 2017, 13:43 ] |
Заголовок сообщения: | Re: код Kotlin & Java |
Olej писал(а): Вот как-то так: Уже пока писался этот тест (и изучался по каждому поводу синтаксис-семантика языка) по нему (по сравнению с Java "по аналогии") можно сделать некоторые выводы: - все объявления (переменные, константы, параметры функций и др.) сделаны в стиле Pascal / Modula / Go, а не C / C++ / Java Вообще, очень и очень много конструкций заимствовано из Go: - порядок объявлений - лябда / анонимные функции, функциональные замыкания ... и вообще всё, что связано с функциональным программированием - множественные возвращаемые значения В каком-то смысле, Kotlin продолжает (развивает) языковую линию Java / Scala ровно в том направлении, в каком Go продолжает (развивает) языковую линию C / C++ ! |
Страница 2 из 3 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |