Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin 入門

oracle4engineer
January 15, 2025

Kotlin 入門

oracle4engineer

January 15, 2025
Tweet

Video

More Decks by oracle4engineer

Transcript

  1. Kotolin 入門 Oracle Cloud Hangout Cafe Season 9 #4 Kyotaro

    Nonaka Solutions Architect Oracle Japan
  2. アジェンダ 1. Kotlin 基礎 1. 基礎知識 2. 文法をざっくり学ぶ 2. Kotlin

    for ... 1. マルチプラットフォーム 2. サーバサイド 3. Android 4. Wasm 5. Native 3. Kotlin を動かしてみる 1. Kotlin Maltiplatform 2. Micronaut with Kotlin 2 Copyright © 2025, Oracle and/or its affiliates
  3. 自己紹介 Kyotaro Nonaka / 野中恭大郎 ソリューション・アーキテクト 日本オラクル株式会社 3 Copyright ©

    2025, Oracle and/or its affiliates @non_kyon • AppDev/Messaging/NoSQL/Frontend • Oracle Cloud Hangout Caféメンバー /Oracle Groundbreakers Advocate • 元ERPパッケージ開発者 • 趣味は釣りとかキャンプとか
  4. Hello world • fun : 関数を定義 • main() : main()

    関数によってプログラムが開始する • {} : {}内に関数の処理を記載する 細かいところでは… • セミコロン不要 • ファイルの拡張子は.kt 7 Copyright © 2025, Oracle and/or its affiliates fun main() { println("Hello, world!") } class Hello { public static void main(String[] args) { System.out.println("Hello World!"); } } Javaと比較すると…
  5. Hello world を CLIコンパイラで動かす CLIコンパイラはSDKMAN!でインストールするのが便利 1. sdk install kotlin 2.

    hello.kt 3. kotlinc hello.kt -include-runtime -d hello.jar 4. java -jar hello.jar 8 Copyright © 2025, Oracle and/or its affiliates fun main() { println("Hello, OCHa Cafe Kotlin!") }
  6. Variables • val : Read-only 変数 • var : Mutable

    変数 • 定数として扱いたいときは const val variablename = ... のように記述 10 Copyright © 2025, Oracle and/or its affiliates val popcorn = 5 // There are 5 boxes of popcorn val hotdog = 7 // There are 7 hotdogs var customers = 10 // There are 10 customers in the queue // Some customers leave the queue customers = 8 println(customers) // 8
  7. String templates • String templatesを使うと、変数を文字列として出力可能 • テンプレート式は$で始まり、コードを実行する場合は {} を使用 11

    Copyright © 2025, Oracle and/or its affiliates val customers = 10 println("There are $customers customers") // There are 10 customers println("There are ${customers + 1} customers") // There are 11 customers
  8. Kotlinの型 • Kotlinは静的型付け言語であり、型推論を行う • 型を明示的に指定したいときは val varname: Byte = 1

    のように記述 12 Copyright © 2025, Oracle and/or its affiliates var customers = 10 // Some customers leave the queue customers = 8 customers = customers + 3 // Example of addition: 11 customers += 7 // Example of addition: 18 customers -= 3 // Example of subtraction: 15 customers *= 2 // Example of multiplication: 30 customers /= 3 // Example of division: 10 println(customers) // 10
  9. Collections Lists : • 追加された順に順序付け • 重複アイテムを許容 • List: Read-OnlyのList、関数はlistOf()

    • MutableList: MutableなList、関数はmutableListOf() 14 Copyright © 2025, Oracle and/or its affiliates // Read only list val readOnlyShapes = listOf("triangle", "square", "circle") println(readOnlyShapes) // [triangle, square, circle] // Mutable list with explicit type declaration val shapes: MutableList<String> = mutableListOf("triangle", "square", "circle") println(shapes) // [triangle, square, circle] アイテムの型 を明示的に 指定可能
  10. Collections Sets : • 順序付けなし • 重複アイテムを許容しない • Set: Read-OnlyのSet、関数はsetOf()

    • MutableSet: MutableなSet、関数はmutableSetOf() 15 Copyright © 2025, Oracle and/or its affiliates // Read-only set val readOnlyFruit = setOf("apple", "banana", "cherry", "cherry") // Mutable set with explicit type declaration val fruit: MutableSet<String> = mutableSetOf("apple", "banana", "cherry", "cherry") println(readOnlyFruit) // [apple, banana, cherry] アイテムの型 を明示的に 指定可能
  11. Collections Maps : • アイテムをキーと値のペアとして格納 • 値にアクセスするには、キーを参照 • Map: Read-OnlyのMap、関数はmapOf()

    • MutableMap: MutableなMap、関数はmutableMapOf() 16 Copyright © 2025, Oracle and/or its affiliates // Read-only map val readOnlyJuiceMenu = mapOf("apple" to 100, "kiwi" to 190, "orange" to 100) println(readOnlyJuiceMenu) // {apple=100, kiwi=190, orange=100} // Mutable map with explicit type declaration val juiceMenu: MutableMap<String, Int> = mutableMapOf("apple" to 100, "kiwi" to 190, "orange" to 100) println(juiceMenu) // {apple=100, kiwi=190, orange=100} KeyとValue の関連付けに to を使う
  12. Basic types Array 配列は、同じ型/サブタイプの値を固定長で保持 • arrayOf() や Arrayコンストラクタで作成 ただし、プラクティスとして、Collections を使用するのが公式の推奨

    • Collections は Read-Only にできる • Array は固定長だが、Collectionsは可変長 • Collections は == で構造的に等しいかどうかが比較できる 17 Copyright © 2025, Oracle and/or its affiliates // Creates an array with values [1, 2, 3] val simpleArray = arrayOf(1, 2, 3) println(simpleArray.joinToString()) // 1, 2, 3 // Creates an Array<String> with values ["0", "1", "4", "9", "16"] val asc = Array(5) { i -> (i * i).toString() } asc.forEach { print(it) } // 014916 Note; ではArrayはいつ使うのか? 公式によると、 • パフォーマンス要件が高いとき • カスタムデータ構造を実装するとき
  13. Control flow 条件分岐 Kotlinの条件分岐には if と when があり、when は複数の条件に枝分かれする処理の際に記述 どちらも使える場合は可読性、柔軟性などの観点から

    when が推奨 18 Copyright © 2025, Oracle and/or its affiliates val d: Int val check = true if (check) { d = 1 } else { d = 2 } println(d) // 1 if val trafficLightState = "Red" val trafficAction = when (trafficLightState) { "Green" -> "Go" "Yellow" -> "Slow down" "Red" -> "Stop" else -> "Malfunction" } println(trafficAction) // Stop when ()で評価する 値を指定 ->で条件が 合致したとき の処理を記述
  14. Control flow Ranges Loopで反復処理を行う範囲(Range)の記述方式を先に解説 • .. • KotlinでRangeを作成する最も一般的な方法 • 1..4は1,

    2, 3, 4と同じ意味 • ..< • 終了値を含まないRangeを宣言する場合に使用 • 1..<4は1, 2, 3と同じ意味 • downTo • 逆順のRangeを宣言する場合に使用 • 4 downTo 1は4, 3, 2, 1と同じ意味 • step n • ステップ値が1以外のRangeを宣言するには、stepと任意の増分値を使用 • 1..5 step 2は1, 3, 5と同じ意味 19 Copyright © 2025, Oracle and/or its affiliates Note; 文字(Char)の範囲でも同じことが可能 • 'a'..'d'は'a', 'b', 'c', 'd'と同じ意味 • 'z' downTo 's' step 2は'z', 'x', 'v', 't'と同じ意味
  15. Control flow Loops • For • While 20 Copyright ©

    2025, Oracle and/or its affiliates for (number in 1..5) { // number is the iterator and 1..5 is the range print(number) // 12345 } val cakes = listOf("carrot", "cheese", "chocolate") for (cake in cakes) { println("Yummy, it's a $cake cake!") } // Yummy, it's a carrot cake! // Yummy, it's a cheese cake! // Yummy, it's a chocolate cake! in 演算子が利用できる
  16. Control flow Loops • While • while : 条件式がtrueである間、コードブロックを実行する •

    do-while : まずコードブロックを実行し、その後条件式を確認する 21 Copyright © 2025, Oracle and/or its affiliates var cakesEaten = 0 while (cakesEaten < 3) { println("Eat a cake") cakesEaten++ } // Eat a cake // Eat a cake // Eat a cake while var cakesBaked = 0 do { println("Bake a cake") cakesBaked++ } while (cakesBaked < 3) // Bake a cake // Bake a cake // Bake a cake do-while
  17. Functions • 関数の引数は()内に記述 • 引数には型を指定する必要があり、複数のパラメーターはカンマで区切る • 戻り値の型は関数の()の後にコロン:で区切って記述 • 関数の本体は波括弧{}内に記述 •

    returnキーワードは、関数からの終了または値の返却に使用 22 Copyright © 2025, Oracle and/or its affiliates fun hello(name: String): String { return "Hello, $name" } fun main() { val name = "OCHaCafe" println(hello(name)) // Hello, OCHaCafe! }
  18. Functions Named arguments • 関数を呼ぶ際に引数名を含める必要はないが、引数名を含めることで可読性が向上 • これをNamed Argumentsと言う • Named

    Argumentsを利用する場合、引数の順序は自由に変更可能 23 Copyright © 2025, Oracle and/or its affiliates fun printMessageWithPrefix(message: String, prefix: String) { println("[$prefix] $message") } fun main() { // Uses named arguments with swapped parameter order printMessageWithPrefix(prefix = "Log", message = "Hello") // [Log] Hello }
  19. Functions Default parameter values • 関数の引数にデフォルト値を定義することが可能 • デフォルト値が設定された引数は、関数を呼び出す際に省略可能 • デフォルト値を宣言するには、型の後に代入演算子(=)を使用

    24 Copyright © 2025, Oracle and/or its affiliates fun printMessageWithPrefix(message: String, prefix: String = "Info") { println("[$prefix] $message") } fun main() { // Function called with both parameters printMessageWithPrefix("Hello", "Log") // [Log] Hello // Function called only with message parameter printMessageWithPrefix("Hello") // [Info] Hello printMessageWithPrefix(prefix = "Log", message = "Hello") // [Log] Hello }
  20. Functions Default parameter values • 関数が値を返す必要がない場合、その戻り値の型はUnitになる • Unitは1つの値(Unit)のみを持つ型 • 関数の本体でUnitを明示的に返す必要はない

    • returnキーワードを使用したり、戻り値の型を宣言したりする必要はありません。 25 Copyright © 2025, Oracle and/or its affiliates fun printMessage(message: String) { println(message) // `return Unit` or `return` is optional } fun main() { printMessage("Hello") // Hello }
  21. Functions single-expression functions • コードをより簡潔にするために、single-expression functionsを使用可能 • {}を省略し、=を使用して関数の本体を宣言可能 • この場合、Kotlinは型推論を行うため、戻り値の型も省略可能

    • ただし、可読性のために戻り値の型は記載するのがプラクティス 26 Copyright © 2025, Oracle and/or its affiliates fun sum(x: Int, y: Int): Int { return x + y } fun sumShortened(x: Int, y: Int) = x + y fun main() { println(sum(1, 2)) println(sumShortened(1, 2)) // 両方とも3 }
  22. Functions Lambda expressions 通常の書き方 ラムダ式 27 Copyright © 2025, Oracle

    and/or its affiliates fun uppercaseString(text: String): String { return text.uppercase() } fun main() { println(uppercaseString("hello")) // HELLO } fun main() { val upperCaseString = { text: String -> text.uppercase() } println(upperCaseString("hello")) // HELLO }
  23. 関数をラムダ式で渡す • filter()やmap()などの評価式として渡すケース (map()は、コレクションの各アイテムを加工するAPI) 28 Copyright © 2025, Oracle and/or

    its affiliates val numbers = listOf(1, -2, 3, -4, 5, -6) val positives = numbers.filter({ x -> x > 0 }) val isNegative = { x: Int -> x < 0 } val negatives = numbers.filter(isNegative) println(positives) // [1, 3, 5] println(negatives) // [-2, -4, -6] Functions Lambda expressions
  24. Function types(関数の型) • Kotlinの型推論は、パラメーターの型から関数の型を推論する • 関数の型を明示的に指定することも可能 記法 • 各引数の型を()内にカンマで区切って記述 ((String)

    -> String または (Int, Int) -> Int のように) • 戻り値の型を->の後に記述 29 Copyright © 2025, Oracle and/or its affiliates val upperCaseString: (String) -> String = { text -> text.uppercase() } fun main() { println(upperCaseString("hello")) // HELLO } Functions Lambda expressions
  25. Classes Properties • クラス名のあとの()でクラスヘッダーを定義 • {}でクラスボディを定義 31 Copyright © 2025,

    Oracle and/or its affiliates class Contact(val id: Int, var email: String) class Contact(val id: Int, var email: String) { val category: String = "" }
  26. Classes Access properties • インスタンスのプロパティにアクセスするには、インスタンス名の後に . を付け、その後にプロパティ名を記述 33 Copyright ©

    2025, Oracle and/or its affiliates fun main() { val contact = Contact(1, "[email protected]") // Prints the value of the property: email println(contact.email) // [email protected] // Updates the value of the property: email contact.email = "[email protected]" // Prints the new value of the property: email println(contact.email) // [email protected] } Note; Java経験者的には、フィールドを直接扱っているこ と?と違和感があるが、実際には暗黙的に getter/setterが定義されており、必要に応じて getter/setterを追記するような形になる
  27. Classes Member functions • Member functions を使用してインスタンス内に関数を定義可能 • Member functions

    はクラス本体の中で宣言する必要がある • 呼び出すには、インスタンス名の後にピリオド(.)を付け、その後に関数名を記述 34 Copyright © 2025, Oracle and/or its affiliates class Contact(val id: Int, var email: String) { fun printId() { println(id) } } fun main() { val contact = Contact(1, "[email protected]") // Calls member function printId() contact.printId() // 1 }
  28. Classes Data classes • データを保存するのに便利 • 通常のクラスと同じ機能に加え、 Member functions を自動的に提供

    • インスタンスを読みやすい形式で出力: toString() • クラスのインスタンス同士を比較: equals() / == • インスタンスをコピー: copy() • クラスごとに同じようなボイラープレートコードを書く手間が省ける 35 Copyright © 2025, Oracle and/or its affiliates data class User(val name: String, val id: Int)
  29. Null safety Kotlinでは、null値を使用することが可能だが、コードがnull値を処理できてない場合に問題 (忘れられないNPE地獄) プログラム内でのnull値の問題を防ぐために、null safety が備わっている • null safety

    は、実行時ではなくコンパイル時に潜在的なnullの問題を検出 • null safety は以下の機能で実現: • プログラム内でnullが許可される場合を明示的に宣言 • nullをチェック • nullを含む可能性のあるプロパティや関数を安全に呼び出す • nullが検出された場合に取るべきアクションを宣言 36 Copyright © 2025, Oracle and/or its affiliates
  30. Null safety Nullable types • nullable type は宣言された型がnullに なる可能性を許容する意味を持つ •

    デフォルトでは、型はnullを許容しない • 型宣言の後ろに?を明示的に追加し、 nullable typeを宣言 37 Copyright © 2025, Oracle and/or its affiliates fun main() { var neverNull: String = "This can't be null" neverNull = null // Throws a compiler error var nullableVar: String? = "You can keep a null here" nullableVar = null // This is OK var inferredNonNull = "The compiler assumes non-nullable" inferredNonNull = null // Throws a compiler error // strはnullになり得ない(?が無いので) fun strLength(str: String): Int { return str.length } println(strLength(neverNull)) // 18 println(strLength(nullableVar)) // Throws a compiler error }
  31. Null safety Check for null values 条件式の中でnullの有無をチェック可能 38 Copyright ©

    2025, Oracle and/or its affiliates fun describeString(maybeString: String?): String { if (maybeString != null && maybeString.length > 0) { return "String of length ${maybeString.length}" } else { return "Empty or null string" } } fun main() { val nullString: String? = null println(describeString(nullString)) // Empty or null string }
  32. Null safety Safe calls • null値を含む可能性のあるオブジェクトのプロパティに安全にアクセスするには、safe call 演算子(?.)を使用 • .?

    はチェーンできる(ex. customer?.orderHistory?.orderId) • safe call 演算子は、オブジェクトまたはそのアクセスされたプロパティがnullの場合にnullを返却 • null値が原因でコードにエラーが発生するのを防ぐ 39 Copyright © 2025, Oracle and/or its affiliates fun lengthString(maybeString: String?): Int? = maybeString?.length fun main() { val nullString: String? = null println(lengthString(nullString)) // null }
  33. Null safety Elvis operator • nullが検出された場合に返すデフォルト値の設定には、Elvis演算子(?:)を使用 • 左側にはnullをチェックする対象を記述、右側にはnullが検出された場合に返す値を記述 40 Copyright

    © 2025, Oracle and/or its affiliates fun main() { val nullString: String? = null println(nullString?.length ?: 0) // 0 } なんでElvis? と思ったら「 ?: 」が Presleyの顔文字(?:j)の 一部だかららしい
  34. Kotlin Multiplatform キー・コンセプト 動作/コンパイルのターゲットとなるプラットフォームには、それに対応するsource setがある source set とは、独自の依存関係やコンパイラオプションを持つ、ソースファイルのセットのこと • source

    set は、そのプラットフォーム専用のライブラリやAPIを使用可能 • 一部のターゲット間でコードを共有する場合、中間ソースセットが使用される • 例えば、appleMainソースセットは、すべてのAppleプラットフォーム間で共有されるコードを表す • すべてのプラットフォーム間で共有され、コンパイルされるコードには、commonMainというソースセットがある 43 Copyright © 2025, Oracle and/or its affiliates
  35. Kotlin Multiplatform expected と actual expected と actual を使用すると、 •

    Kotlin Multiplatform からプラットフォーム固有のAPIを利用可能 • 共通コード内でプラットフォームに依存しないAPIを提供することが可能 44 Copyright © 2025, Oracle and/or its affiliates
  36. Kotlin for server side Kotlinはサーバーサイド開発にも向く • 表現力: Type-safe Builder や

    Delegated Propertiesのような機能により、強力で使いやすい抽象化を構築 • スケーラビリティ: Coroutinesを活用し、控えめなスペックでも多数のクライアントに対応できるサーバ・アプリを構築 • 相互運用性: Javaフレームワークとの互換性により、既存の技術スタックの中でよりモダンな言語の利点を享受 • 移行: 大規模なコードベースをJavaからKotlinに段階的に移行可能 • ツールサポート: IDEサポートや、特定のフレームワーク向けのツールをIntelliJ(Ultimate)のプラグイン内で提供 • 学習曲線: Kotlinプラグインに含まれるJava-to-Kotlin変換ツール 45 Copyright © 2025, Oracle and/or its affiliates
  37. Kotlin for server side Type-safe Builder • 型安全で静的に型付けされたビルダーを作成することが可能 • Kotlinでドメイン固有言語(DSL)を作成できる

    • 複雑な階層型データ構造を半宣言型の方法で構築するのに適する • よくあるユースケースとしては、動的なHTML/XMLなどの出力をKotlinで行う 46 Copyright © 2025, Oracle and/or its affiliates val result = html { head { title { +"HTML encoding with Kotlin" } } body { h1 { +"HTML encoding with Kotlin" } p { +"this format can be used as an" +"alternative markup to HTML" } a(href = "http://kotlinlang.org") { +"Kotlin" } p { +"This is some" b { +"mixed" } +"text. For more see the" a(href = "http://kotlinlang.org") { +"Kotlin" } +"project" } p { +"some text" ul { for (i in 1..5) li { +"${i}*2 = ${i*2}" } } } } } <html> <head> <title> HTML encoding with Kotlin </title> </head> <body> <h1> HTML encoding with Kotlin </h1> <p> this format can be used as an alternative markup to HTML </p> <a href="http://kotlinlang.org"> Kotlin </a> <p> This is some <b> mixed </b> text. For more see the <a href="http://kotlinlang.org"> Kotlin </a> project </p> <p> some text <ul> <li> 1*2 = 2 </li> --- 中略 --- <li> 5*2 = 10 </li> </ul> </p> </body> </html> 実行 (resultの中身)
  38. Kotlin for server side Delegated Properties Classのプロパティの中には、そのつど実装するより、共有/共通 なライブラリ側に実装し、後で再利用する方が便利なものがある • 遅延プロパティ(Lazy

    properties): 初回アクセス時にの み評価 • オブザーバブルプロパティ(Observable properties): プロ パティの変更についてリスナーに通知 47 Copyright © 2025, Oracle and/or its affiliates import kotlin.properties.Delegates class DelegateProps { val lazy: String by lazy{ println("初回だけの処理") "処理" } var obsv: String by Delegates.observable("<empty>") { prop, old, new -> println("$old -> $new") } } fun main() { val lzy = DelegateProps().lazy println(lzy) println(lzy) val props = DelegateProps() props.obsv = "ocha" props.obsv = "cafe" }
  39. Kotlin for server side Coroutines Coroutineは並行処理のデザインパターンで、非同期実行するコードを簡略化 メインスレッドをブロックしてアプリの応答を止める可能性のある長時間実行タスクの管理に役立つ 48 Copyright ©

    2025, Oracle and/or its affiliates import kotlinx.coroutines.* fun main() = runBlocking { // Coroutineのスコープ launch { // Coroutineの開始 delay(2000L) // 2秒停止 println("Cafe!") // 停止後の処理 } launch { delay(1000L) // 1秒停止 println("OCHa!") // 停止後の処理 } println("Hello") // まず最初に実行される }
  40. Kotlin for server side Spring : バージョン5.0からKotlinの言語機能を活用して、より簡潔なAPIを提供 Ktor : JetBrainsが開発したKotlinでWebアプリケーションを作成するためのフレームワーク

    Quarkus : Kotlinの利用をfirst-classサポートするフレームワークで、Red Hatによって管理されるオープンソース Vert.x : JVM上でリアクティブなWebアプリケーションを構築するためのフレームワーク kotlinx.html : WebアプリケーションでHTMLを構築するためのDSL Micronaut : マイクロサービスやサーバーレスアプリケーションを構築するためのJVMベース・フルスタックフレームワーク http4k : Kotlin HTTPアプリケーション向けの機能的ツールキット Javalin : KotlinとJava向けの非常に軽量なWebフレームワーク kotlin-jpa : JPAを使用する場合に使用するコンパイラプラグイン 49 Copyright © 2025, Oracle and/or its affiliates フレームワーク事情
  41. Kotlin for Android JetpackライブラリのKotlinサポート • Jetpack Compose : KotlinでネイティブUIを構築するためのAndroid推奨のツールキット •

    KTX拡張機能 : Coroutines/ラムダ式/名前付きパラメータなどの機能を既存のAndroidライブラリに追加 マルチプラットフォーム開発のサポート • Kotlin Multiplatformを使用すると、Androidだけでなく、iOS、バックエンド、ウェブアプリケーションも開発 • JetBrainsが開発したKotlinとJetpack Composeをベースとする宣言型UIフレームワークであるCompose Multiplatformを使用すれば、iOS、Android、デスクトップ、ウェブをまたいでUIを共有することが可能 Javaとの互換性 • KotlinはJavaプログラミング言語と共存できるため、すべてのコードをKotlinに移行する必要はない • Kotlinは特にJava開発者にとって学習が非常に簡単 50 Copyright © 2025, Oracle and/or its affiliates
  42. Kotlin/Wasm (Alpha) そもそもWasm(WebAssembly)とは? WebAssembly はウェブブラウザーで実行できる新しい種類のコード • ネイティブに近いパフォーマンスで動作 • コンパクトなバイナリー形式の低レベルなアセンブリー風言語 •

    C/C++、C# や Rust などの言語のコンパイル先となり、それらの言語をウェブ上で実行可能 • WebAssembly は JavaScript と並行して動作するように設計 51 Copyright © 2025, Oracle and/or its affiliates
  43. Kotlin/Wasm (Alpha) Kotlin/Wasm は、KotlinコードをWebAssembly(Wasm)形式にコンパイル可能 さまざまなターゲット環境で使用可能 • Compose Multiplatform を使用して構築されたウェブアプリケーションを開発するためにブラウザで使用 •

    ブラウザ外部のスタンドアロンの Wasm 仮想マシンで実行するために使用 • WebAssembly System Interface(WASI)を利用することで、プラットフォームAPIへのアクセスも可能 Kotlin/Wasm 上で実行される Compose Multiplatform はJSよりもパフォーマンスが良いという結果が出ている 52 Copyright © 2025, Oracle and/or its affiliates
  44. Kotlin Multiplatform を試してみる ウィザードを使用してプロジェクトを作成する 1. Android Studio のダウンロードとインストール 2. KMP

    Plugin をインストール 3. Kotlin Multiplatform ウィザードを開く 4. [新しいプロジェクト]タブで、 1. プロジェクト名を「GreetingKMP」 2. プロジェクト ID を「com.jetbrains.greeting」 5. Android と Web のオプションが選択されていることを確認 6. [ダウンロード]ボタンをクリックし、生成されたアーカイブを解凍 55 Copyright © 2025, Oracle and/or its affiliates
  45. Kotlin Multiplatform を試してみる ウィザードを使用してプロジェクトを作成する 1. 解凍したプロジェクトを開く 2. composeApp/src/commonMain/kotlin/.../Greeting.kt を開く 3.

    中身を以下のように書き換える 56 Copyright © 2025, Oracle and/or its affiliates package com.jetbrains.greeting import kotlin.random.Random class Greeting { private val platform: Platform = getPlatform() fun greet(): String { val firstWord = if (Random.nextBoolean()) "Hi!" else "Hello!" return "$firstWord Guess what this is! > ${platform.name}!" } }
  46. Micronaut with Kotlin Micronaut公式を参考にして(Mavenなのは私が古いルーツを持つ人間だから) 1. Micronaut CLI をインストール 2. mn

    create-app example.micronaut.micronautguide --build=maven --lang=kotlin 3. src/main/kotlin/example/micronaut/Application.kt を作成 4. src/main/kotlin/example/micronaut/HelloController.kt を作成 5. ./mvnw mn:run 6. curl –X GET http://localhost:8080/hello 57 Copyright © 2025, Oracle and/or its affiliates package example.micronaut import io.micronaut.http.MediaType import io.micronaut.http.annotation.Controller import io.micronaut.http.annotation.Get import io.micronaut.http.annotation.Produces @Controller("/hello") class HelloController { @Get @Produces(MediaType.TEXT_PLAIN) fun index() = "Hello World" } package example.micronaut import io.micronaut.runtime.Micronaut.run fun main(args: Array<String>) { run(*args) } 3 4
  47. Micronaut with Kotlin Javaとの互換性を確かめてみる src/main/kotlin/example/micronaut/HelloController.kt を以下のように変更する 58 Copyright © 2025,

    Oracle and/or its affiliates package example.micronaut import io.micronaut.http.MediaType import io.micronaut.http.annotation.Controller import io.micronaut.http.annotation.Get import io.micronaut.http.annotation.Produces import java.util.* @Controller("/hello") class HelloController { @Get @Produces(MediaType.TEXT_PLAIN) fun index() : String { val properties: java.util.Properties = java.lang.System.getProperties() properties.list(java.lang.System.out); return "Hello World" } }