Kotlin
メインページ > 工学 > 情報技術 > プログラミング > Kotlin
Kotlinは、JetBrains社によって開発された静的型付けされたオブジェクト指向のプログラミング言語で、Java仮想マシン(JVM)上で動作します。JavaScriptや、LLVMフレームワークを介して多くのプラットフォームで実行可能なコードにもコンパイルできます。 また、Kotlin/Wasmは、Kotlinの新しいコンパイルターゲットであり、WebAssemblyをサポートする環境やデバイス上で実行可能なアプリケーションを作成することができます。これにより、Kotlinの強力な機能と柔軟性を活用して、Webアプリケーションやクライアントサイドのプログラミングにも取り組むことができます。
KotlinはJavaよりも簡潔で型安全性が高く、Scalaよりもシンプルな言語を目指して開発されました。Scalaと比較して、簡略化された結果、コンパイルが高速化され、IDEでの言語サポートも充実しています。また、KotlinはJavaと完全な互換性があり、Java開発者は徐々に導入することができます。特に、KotlinはAndroidにも組み込まれており、既存のAndroidアプリケーションは、アプリケーション全体を書き換えることなくKotlinで新機能を実装することができます。Kotlin FoundationがKotlinTM商標を守っています。
はじめに

Kotlinは多様なプラットフォームで利用できるモダンで柔軟なプログラミング言語です。
はじめに

このチュートリアルに取り組む前に、以下の予備知識が役立ちます。
はじめに

以上の予備知識を持っていると、Kotlinをより効果的に学習し、異なるプラットフォームでの利用に対応することができます。各プラットフォームにおけるKotlinの特徴や最適な利用法を理解することで、幅広い開発環境で柔軟かつ効率的なプログラミングが可能になります。
はじめに

Kotlinを学ぶ際に他の言語のプログラミング経験がある場合、以下のアドバイスが役立つかもしれません。
はじめに

総じて、Kotlinは他のプログラミング言語において得た経験を活かしやすい言語です。適応期間は短く、生産性を高めるために積極的に新しい機能や手法を試してみることが重要です。また、公式のドキュメントやサンプルコードを利用して、Kotlinの言語仕様やベストプラクティスに精通することもおすすめです。
はじめに

プログラミング未経験者がKotlinやプログラミング全般に取り組む際のアドバイスは以下の通りです:
はじめに

プログラミングは絶え間ない学習が求められる分野です。新しい技術やツールに興味を持ち、継続的に学び続けることでスキルを向上させることができます。
はじめに

プログラミングはスキルの向上に時間がかかるものですが、継続的な努力と実践を通じて着実に成長していきます。最初は小さなステップから始め、徐々に進んでいくことが大切です。
はじめに

他の多くのチュートリアルがそうであるように、 私たちもまずはKotlinの世界にあいさつすることから始めましょう。hello.ktというファイルを作り、次のように書いて保存して下さい(Kotlinのソースファイルの拡張子は .kt です)。
はじめに

それでは、ソースプログラムをコンパイルして実行してみましょう。
はじめに

これにより、この一行のコードは「mainという関数を宣言し、その中で 'Hello, World!' という文字列をコンソールに表示する」という単純なプログラムを実現しています。Kotlinはこのようにシンプルかつ読みやすい構文を持っており、初学者にも優れた学習言語となっています。
はじめに

Kotlinのクイックツアーでは、基本的な構文や機能に焦点を当て、簡単なコード例を通じて言語の特徴を理解していきます。
はじめに

この例では、Kotlin DSLを使用して、特定のドメイン(ここではPersonオブジェクトの構築)に特化した言語拡張を行っています。
はじめに

これらの例はKotlinの基本を紹介するものであり、より高度な概念や機能も学ぶことができます。
インストール方法

Kotlinは、ターゲットごとに
インストール方法

の3つの実装があり、ツールチェインとしては統合されていますが、使用するコマンドやオプションが異なります。
インストール方法

Kotlin/JVM 環境をインストールする手順は以下の通りです:
インストール方法

以上で、Kotlin/JVM 環境のインストールが完了します。
実行方法

Kotlin/JVM では、Kotlin のソースファイルからJARファイルをコンパイルします。 Kotlin のソースファイルの拡張子は .kt です。
実行方法

hello.kt をコンパイルして hello.jar を得るのであれば
実行方法

生成された hello.jar を実行するには
実行方法

別のKotlinのソースファイル universe.kt をコンパイル/実行するには hello を filename に読替えて同じ手順を行えばいいのですが、このような単純作業はコンピューターに任せましょう。
実行方法

ビルド手順の自動化を行うツールに make があります。 make にはいくつかの方言がありますが、BSD-make と GNU-make に共通した構文を紹介します。
実行方法

コマンドラインでの操作は
実行方法

この様に、make を使うとファイルのタイムスタンプから必要な処理を判断し実行します。
実行方法

make と同じくビルドツールに gradle があり、gradle のビルドルールは Kotlin Script で書けるので、Kolin の学習には gradle が適しているとも言えますが、ビルドルールを書くためにKotlinのコードを読み書きする必要があるという「鶏卵問題」に陥るので、より一般的な make を紹介しました。
実行方法

ここでは、kotlinソースからJARファイルをコンパイルし実行する最小限のルールを書きましたが、機会をみて、make のチュートリアルを書こうと思います。
コード・ギャラリー

エラトステネスの篩を、若干 Kotlin らしく書いてみました。
コード・ギャラリー

最大公約数と最小公倍数を、若干 Kotlin らしく書いてみました。
コード・ギャラリー

それぞれの関数定義は式形式で1行なので拍子抜けですが、概念を簡素にかけていると思います。
コード・ギャラリー

二分法を、若干 Kotlin らしく書いてみました。
コード・ギャラリー

オーソドックスな複素数型の実装(Kotlinの標準ライブラリーには複素数型が見当たらなかったので)
KotlinとJavaの比較

KotlinとJavaは、どちらもJava Virtual Machine(JVM)上で動作するプログラミング言語です。以下は、KotlinとJavaの主な比較ポイントです。
KotlinとJavaの比較

総合的に見ると、KotlinはJavaよりも簡潔で読みやすく、より現代的な言語機能を備えています。ただし、Javaのライブラリやフレームワークを使用する場合は、Javaを使用することが必要な場合があります。
KotlinとScalaの比較

KotlinとScalaは、どちらもJVM(Java Virtual Machine)上で動作する静的型付け言語であり、それぞれ異なる特徴を持っています。以下に、KotlinとScalaをいくつかの側面で比較してみます。
KotlinとScalaの比較

総合的に見ると、KotlinはJavaからの移行が容易であり、Androidアプリケーションの開発に特に適しています。一方で、Scalaは関数型プログラミングの特徴を生かして複雑なシステムの開発に向いており、高度な拡張性を提供しています。選択する言語は、開発の目的や開発者のスキルセットによって異なることがあります。
KotlinとSwiftの比較

KotlinとSwiftは、それぞれAndroidとiOSのアプリ開発で主に使用されるプログラミング言語です。以下に、両言語の類似点と相違点をいくつか挙げてみます。
KotlinとSwiftの比較

どちらの言語も優れた特性を持っており、選択はプロジェクトのニーズや開発者の好みによって異なります。
エントリーポイント

Kotlinでは、関数 mainがエントリーポイントです。
エントリーポイント

なにもしないプログラムはこの様になります。
パッケージ

パッケージの指定は、ソースファイルの冒頭(shebang!の次)で行ってください。
パッケージ

ディレクトリとパッケージの一致は必須ではなく、ソースファイルはファイルシステム上に任意に配置することができます。
パッケージ

Kotlinでは、特定のパッケージやクラスを明示的にインポートすることなく、いくつかのデフォルトのインポートが提供されています。これにより、コードをより簡潔にし、冗長性を減少させることができます。以下は、デフォルトでインポートされる主要なパッケージです。
パッケージ

また、ターゲットプラットフォームに応じて、追加のデフォルトインポートが行われます。
パッケージ

上記のパッケージは、明示的にインポートすることなく既にインポートされています。
パッケージ

このようなデフォルトのインポートにより、開発者は冗長なコードを書かずに済み、効率的にKotlinの機能を利用することができます。
パッケージ

以下は、デフォルトでインポートされる主要なパッケージの概要を表形式でまとめたものです。
パッケージ

また、ターゲットプラットフォームによっては、追加のデフォルトインポートが行われます。
パッケージ

これらのデフォルトインポートは、通常のKotlinプロジェクトで基本的な操作や機能を利用するための便利な手段となります。
パッケージ

デフォルトインポートとは別に、各ファイルは独自の import ディレクティブを含むことができます。
パッケージ

単一の名前でインポートすることができます。
パッケージ

または、パッケージ、クラス、オブジェクトなどのスコープのすべてのアクセス可能なコンテンツをインポートすることができます。
パッケージ

名前の衝突がある場合、as キーワードを使用して、衝突するエンティティの名前をローカルに変更することで、曖昧さをなくすことができます。
パッケージ

import キーワードは、クラスのインポートに限定されません。他の宣言をインポートするためにも使用することができます。
パッケージ

トップレベル宣言が private とマークされている場合、その宣言が行われたファイルに対してプライベートとなります。
トップレベルオブジェクト

いかなる関数スコープにも属さないオブジェクトのことを、トップレベルオブジェクト( top level object )と言います。
コメント

Kotlinには、行末で終わるコメントと、複数行に渡ることと、入れ子にすることができるコメントがあります。
基本型

Kotlinでは、任意のインスタンスに対してプロパティーを参照したりメンバー関数を呼出すことができるという意味で、すべてのインスタンスがクラスに属しています。 いくつかの型は特別な内部表現を持つことができます。例えば、数字、文字、ブール値は実行時にプリミティブ値として表現できますが、ユーザーからは参照されるときに自動的にボックス化されるので普通のクラスのインスタンスのように見えます。 これらの型は基本的にJavaのプリミティブに一対一に対応しますが、Stringだけはjava.lang.Stringクラスに対応しています。 基本型は Package kotlin で定義されています。
基本型

Kotlinの論理型は Boolean で
基本型

の2つの値以外は取りえません。
基本型

JVMでは、この型の非Nullable値は、プリミティブ型のbooleanの値として表現されます。 論理型と数値型は可換ではないので、制御構造の条件式などでもゼロとの比較を行う必要があります。
基本型

Kotlinの数値型は、整数型と浮動小数点数型に分かれています。 これらの型は、抽象クラスである Number クラスから派生しており、具象クラスとして利用されます。
基本型

なお、文字型は数値型と可換ではありません。
基本型

Kotlinの整数型には、符号付き整数型と符号なし整数型があります。 符号なし整数型の名前は、対応する符号付き整数型の名前の先頭に U を補ったものになります。以下が主な整数型です:
基本型

Kotlinの浮動小数点数型には、以下の2つがあります:
基本型

これらの数値型は、数学的な演算や精密な計算に利用され、Kotlin言語において数値処理をサポートする基本的な要素となっています。
基本型

Charクラスは文字を表すクラスです。'a' のようなKotlinプログラム内の文字リテラルはすべてこのクラスのインスタンスとして実装されています。 Charは、16ビットのUnicode文字を表します。これは、Charがすべての文字をユニコード文字を表すことが出来ない事をしめしています。
基本型

Kotlinは、Javaの文字エンコーディングシステムを引継いだので、Charの収まらない文字の問題に限らずUnicodeを内部エンコーディングに使っていることに起因する厄介ごとと付き合い続ければなりません。
基本型

Charでは、いくつかの演算子が定義されています。
基本型

特殊文字は、エスケープする \(バックスラッシュ)から始まります。以下のエスケープシーケンスに対応しています。
基本型

その他の文字をエンコードする場合は、Unicodeエスケープシーケンス構文を使用します。'\uFF00' を使用します。
基本型

String クラスは文字列を表すクラスです。"abc" のようなKotlinプログラム内の文字列リテラルはすべてこのクラスのインスタンスとして実装されています。 Kotlinでは、文字列( String )と文字( Char )とは直接の関係はありません(StringはCharの配列ではありません)。
基本型

Stringでは、加算演算子を連結として定義されています。
基本型

加算演算子( + )は、文字列( this )と与えられた他のオブジェクトの文字列表現を連結して得られる文字列を返します。
基本型

既に紹介したように、Stringクラスのリテラルは "(ダブルクオーテーション)で括った文字列です。
基本型

Stringリテラルには変数や式を埋込むことが出来ます。 このように、変数や式が埋込まれたStringリテラルのことをテンプレートリテラルといいます。
基本型

生文字列( Raw strings )は、改行や任意のテキストを含むことができます。トリプルクォート(”””; triple quote )で区切られ、エスケープを含まず、改行や他の任意の文字を含むことができます。
基本型

Kotlinで配列型は Array で、main() の引数でも使われています。
基本型

Array(), arrayOf(), arrayOfNulls() や emptyArray() で生成します。
基本型

Kotlinには、IntArray、DoubleArray、BooleanArray、CharArrayなどのプリミティブ型を要素とする配列のクラスが用意されています。 これらを総称してプリミティブ型配列( Primitive type arrays )と呼びます。 プリミティブ型配列は、機能的にはArray<T>のTにプリミティブ型を与えたものと変わりありませんが、ボックス化されないので性能向上とフットプリントの削減が期待できます。 このため、プリミティブ型配列はArrayを継承していません。
基本型

StringArray はありません。
特別な型

基本型の他にも幾つかの特別な型があります。 これらは、基本型同様 Package kotlin で定義されています。
特別な型

AnyはKotlinのクラス階層のルートです。すべてのKotlinクラスはAnyをスーパークラスとして持っています。 クラス定義で継承元を指定しないと Any が暗黙の継承元になります。 また、Anyクラスのオブジェクトは、あらゆるオブジェクトを代入できます。
特別な型

Unitは、何も返さない関数の戻値の型です。JVMでは、Javaのvoid型に相当します。
特別な型

は
特別な型

と等価です。
特別な型

Nothingはインスタンスを持ちません。例えば、ある関数の戻り値がNothingであれば、それは決して戻らない(常に例外を投げる)ことを意味します。
Null安全

KotlinのNULL安全性(Null safety)とNullableに関して、以下のポイントが重要です。
Null安全

KotlinのNull安全性とNullable型は、プログラミングにおける安全性と信頼性を向上させるための重要な機能です。これらの機能を適切に理解し、利用することで、Nullによるエラーを最小限に抑えることができます。
Null安全

Javaを含む多くのプログラミング言語における最も一般的な落とし穴の1つは、Null参照のメンバーにアクセスするとNull参照例外が発生することです。Javaでは、これはNullPointerException、略してNPEと呼ばれるものに相当します。
Null安全

KotlinでNPEが発生する原因として考えられるのは、以下の通りです。
Null安全

Kotlinの型システムでは、nullを保持できる参照(Null可能参照; nullable references )とそうでない参照(非Null参照; non-null references )を区別しています。例えば、String型の通常の変数はnullを保持できません。
Null安全

nullを許容するには、String?と書いて変数をnull可能な文字列として宣言します。
Null安全

さて、aのメンバー関数を呼び出したり、プロパティーにアクセスしたりしても、NPEが発生しないことが保証されています。
Null安全

しかし、bのメンバー関数を呼び出したり、プロパティーにアクセスしたりすると、それは安全ではなく、コンパイラはエラーを報告します。
Null安全

それでもそのプロパティにアクセスする必要がありますよね?そのためには、いくつかの方法があります。
Null安全

まず、bがnullかどうかを明示的にチェックし、2つの選択肢を別々に処理することができます。
Null安全

コンパイラーは実行したチェックの情報を記録し、ifの内部でlengthの呼出しを可能にする。より複雑な条件もサポートされています。
Null安全

註:b が immutable な場合 (つまり、チェックから使用までの間に変更されないローカル変数か、 バッキングフィールドを持つオーバーライド不可のメンバー変数) にのみ有効です。
Null安全

Not-Null断定演算子(!!)で任意の値をnullでない型に変換し、値がnullの場合は例外をスローします。b!!と書くと、bの非null値(例えばこの例ではString)を返し、bがnullの場合はNPEを投げます。
Null安全

このように、NPEを発生させたい場合は、明示的に要求する必要があり、突然発生することはありません。
Null安全

?. 演算子は、null安全性を保証しつつ、str 変数がnullでない場合に length プロパティにアクセスします。str がnullの場合、length には null が代入されます。
Null安全

このように、?. 演算子はnull値を安全に処理するために使用されます。例えば、Javaの場合、nullチェックを行わないとNullPointerExceptionが発生しますが、Kotlinでは ?. 演算子を使用することで、nullに対する操作を安全に行うことができます。
識別子

変数の名前のような名前を識別子( identifiers )と呼びます。 変数ほかに、関数、クラス、クラスのメンバー、クラスのメンバー関数、enum、ラベルなどの名前も識別子です。
変数

Kotlinでは、変数は使う前にかならず宣言する必要があります。
変数

いままでの例で既に型推論( type inference ) は使われています。 変数を宣言するときに、特に型を明示しませんでしたが、初期化式の型から変数の型を特定していたのです。
変数

初期化式は省略可能です。 その場合は変数の型がわからないので型アノテーション( type annotation )が必要になります。
変数

シャドーイング( Shadowing )とは、スコープ内の2つの宣言が同じ名前になり、より内側の識別子が外側の識別子を隠すことです。
変数

多くのシャドーイングは無害ですが...
変数

オブジェクトを複数の変数に分解して初期化する宣言する方法があり、分解宣言( Destructuring declarations )と呼ばれます。
演算子

Kotlinでは、演算子はメソッド形式の別名を持ちます。 例えば、a + b は a.plus(b) とも書けます。 この plus メンバー関数を再定義すると、演算子オーバーロードができます。
演算子

演算子は、もちろん加算だけではありません。
制御構造

Kotlinは、if と when の2つの分岐構文を持ち、両方とも値を返す式です。
制御構造

if式は、条件式に基づき分岐し、分岐先の式を評価します。 if式の値は、分岐先の式の値です(C言語系の三項演算子に相当する働きをします)。 if式の値を右辺値化した場合、else節は必須です。
制御構造

if や while の条件式は
制御構造

でなければいけません。
制御構造

when式を使って条件分岐をすることができます。 when 式は、when に与えられた式(境界値)に最初にマッチするパターンに結びついた値を返すパターンマッチングです。 式が省略されると、パターンの条件が最初に真になるパターンに結びついた値を返します。
制御構造

whenは式なので以下のように書換えることができます。
制御構造

区切子 -> を使った構文の左辺の条件には、以下のようなバリエーションがあります。
制御構造

when 文は、多くの条件分岐をシンプルに表現するための強力な構造です。境界値が省略された場合、true が境界値とみなされます。
制御構造

when 文を使うことで、このような条件分岐をより簡潔に表現できます。
制御構造

境界値を省略した例として、以下のコードを見てみましょう。
制御構造

このコードでは、when 文が x の値に基づいて文字列を返します。境界値が省略されているため、条件が true のブロックが実行されます。
制御構造

when 文を使用してループから脱出する例もあります。以下は、when 文を使って特定の条件でループを脱出する例です。
制御構造

このコードでは、when 文を使用して number が3の場合にループから脱出します。
制御構造

enum クラスを使った when 文の例も挙げてみましょう。
制御構造

このコードでは、enum クラス Day を使用して、曜日に応じた活動を選択しています。when 文が enum の各ケースを処理し、対応する活動が選択されます。
制御構造

Kotlinには、while・do-while と for の3つの繰返し構文があります。これらは文で、値を返すことはできません。
制御構造

whileは、条件式が true の間、式を評価しつづけます。
制御構造

do-whileは、条件式が true の間、式を評価しつづけるという意味では、whileと同じですが、条件式がループの最後にある、つまり条件が成立しなくても1周はループが回ることが異なります。
制御構造

Kotlinのforはw:foreach文タイプのループ構文で、C言語の for(;;) とは異なる構文です。
関数

関数は、キーワード fun を使って定義します。
関数

関数のボディが単一の式からなる場合、{ return 式 } を、= 式と書くことができます。
関数

初見だと驚きますが、関数型プログラミング風の書き方が簡素にできます。 特に、ifやwhenが値を返すことができる式であることが効いてきます。
関数

ボディが単一の式からなる関数定義では、戻値式の型が推論できる場合が多いので、戻値型を省略できる場合があります。
関数

再帰関数の戻値型を省略しようとすると、自分自身が型不明な項になりコンパイルできません。
関数

関数の引数はイミュータブルです。 これは Zig も同じで、新興言語は不用意な書換えによる古参言語で度々アクシデントのもととなった引数の破壊を永久になくしたいようです。
関数

関数には、引数にディフォルト値を設定できます。これにより、呼び出し側は引数を指定しなくても関数を呼び出すことができます。
関数

たとえば、次の関数は、名前と年齢の2つの引数を取ります。名前には「John Doe」というデフォルト値が設定されています。
関数

この関数を呼び出すには、名前を指定するか、デフォルト値を使用できます。
関数

関数の引数にデフォルト値を設定すると、呼び出し側がすべての引数を指定する手間を省くことができます。また、関数の使い方を覚えやすくすることもできます。
関数

次のコードは、関数指向の構文を使用して関数を呼び出す方法を示しています。
関数

このコードは、add 関数を呼び出して、2つの引数 1 と 2 を渡します。add 関数は、これらの引数を受け取った後、それらを加算して結果を返します。関数 main は、結果をコンソールに出力します。
関数

次のコードは、メソッド指向の構文を使用して関数を呼び出す方法を示しています。
関数

このコードは、Person クラスのインスタンスを作成し、name プロパティに John Doe という値、age プロパティに 30 という値を設定します。次に、greet メソッドを呼び出して、インスタンスの名前を出力します。
関数

Kotlin は関数を呼出す時、引数を名前で指定する事ができます。
関数

関数修飾子 infix を使うと、中置表現の関数呼出しを行うことができるようになります。外観は文法を拡張したかのような印象をうけます。
関数

関数スコープは、変数や関数が定義され、利用可能な範囲を指します。Kotlinでは、関数スコープ内で定義された変数や関数はそのスコープ内でのみアクセス可能で、外部のスコープからは見えません。
関数

以下に、関数スコープの基本的な特徴と例を示します。
関数

この例では、main 関数が外部のスコープで、myFunction が関数スコープ内で宣言されています。main 関数内では outerVariable にアクセスでき、myFunction 内では innerVariable と innerFunction にアクセスできます。ただし、逆は成り立ちません。
関数

関数スコープは、変数や関数の可視性を制御し、プログラムの構造を整理する上で重要な役割を果たします。関数ごとにスコープが分離されるため、変数や関数の名前の衝突を防ぎ、コードの保守性を向上させます。
関数

可変長引数( Variable-Length Arguments )は、関数が異なる数の引数を受け入れることを可能にする Kotlin の機能です。これは vararg キーワードとスプレッド演算子( spread operator )を使用して実現されます。
関数

このように、関数を呼び出す際に異なる数の引数を渡すことができます。可変長引数は、同じ型の引数が複数個ある場面で便利です。
関数

スプレッド演算子( Spread Operator )は、リストや配列などの要素を展開して、可変長引数として渡すための演算子です。
関数

この例では、arrayOf で作成した配列の要素をスプレッド演算子 * を使って myVaPrint 関数に渡しています。これにより、配列の各要素が可変長引数として関数に渡されます。
関数

可変長引数とスプレッド演算子の組み合わせにより、異なる数の引数を柔軟に扱うことができ、関数の再利用性を向上させます。
関数

引数あるいは戻値あるいは両方が関数の関数を高階関数()と呼びます。
関数

ラムダ式( lambda expressions )では、波括弧の周囲と、パラメータと本体を分ける矢印の周囲に空白を使用する必要があります。ラムダを1つだけ指定する場合は、可能な限り括弧で囲んでください。
関数

また、ラムダのラベルを指定する場合、ラベルと中括弧の間にスペースを入れてはいけません。
関数

上記のラムダ式構文には、関数の戻値の型を指定する機能がひとつだけ欠けています。ほとんどの場合、戻値の型は自動的に推測されるため、この指定は不要です。しかし、明示的に指定する必要がある場合は、別の構文として無名関数( Anonymous functions )を使用することができます。
関数

ラムダ式や無名関数(ローカル関数やオブジェクト式も同様)は、外部スコープで宣言された変数を含むクロージャー( Closures )にアクセスすることができます。クロージャーに取り込まれた変数は、ラムダ式で変更することができます。
関数

高階関数を使用すると、ある種の実行時ペナルティーが課せられます。各関数はオブジェクトであり、クロージャーを捕捉します。クロージャー( closure )とは、関数本体でアクセス可能な変数のスコープです。メモリー確保(関数オブジェクトとクラスの両方)と仮想呼出しは、実行時オーバーヘッドを発生させます。
関数

しかし、多くの場合、ラムダ式をインライン化することで、この種のオーバーヘッドをなくすことができます。
関数

Kotlin は、特に修飾辞なしに関数を再帰呼び出しできます。
関数

tailrec は、Kotlinのキーワードで、末尾再帰最適化(Tail Recursion Optimization)を実現するために使用されます。末尾再帰最適化は、再帰関数が最後の操作として再帰呼び出しを行う場合に、スタックの消費を減少させる最適化手法です。これにより、スタックオーバーフローを避けることができます。
関数

上記の例では、factorial 関数が末尾再帰関数として宣言されています。再帰呼び出しは末尾で行われており、コンパイラが最適化を行うことが期待されます。
関数

tailrec を使用するためにはいくつかの制約があります。
関数

tailrec を使うと、再帰関数の性能を向上させることができます。ただし、制約を理解し、満たすことが重要です。tailrec が適用される場合、コンパイラはループに変換し、スタックの使用を最小限に抑えます。
拡張

Kotlinでは、クラスやインターフェースを継承したり、Decoratorのようなデザインパターンを使わずに、新しい機能を拡張することができます。これは、拡張( extensions )と呼ばれる特別な宣言によって実現されます。
拡張

拡張関数( Extension functions )を宣言するには、その名前の前に拡張される型を示すレシーバー型をつけます。以下は、Array<Int>にrotate関数を追加したものです。
拡張

拡張関数でもジェネリックス(型パラメーター)が使用可能です。
拡張

先の例は、Array<Int>とIntのアレイ専用でしたが、任意の型 T のアレイ Array<T> に拡張関数を拡張してみましょう。
拡張

拡張は、一見するとクラスの中に後からメンバー関数を追加しているように見えるかもしれませんが、インスタンス.メソッド(実引数リスト) のパターンに合致する拡張定義があるかを静的に調べ、該当する拡張関数があればそれを呼出すことで実現しています。
拡張

このため拡張関数でメンバー関数をオーバーライドすることはできません。
クラス

Kotlinは関数型プログラミング言語であると同時に、クラスベースのオブジェクト指向プログラミング言語です。 クラス( class )はオブジェクトの設計図であり、インスタンスはその設計図に基づいて作成されます。
クラス

クラスは、キーワード classを使って定義します。
クラス

Kotlinのクラスはプライマリーコンストラクターと1つまたは複数のセカンダリーコンストラクターを持つことができます。プライマリーコンストラクターはクラスヘッダの一部で、クラス名とオプションの型パラメターの後に続きます。
クラス

メンバー関数は、クラス定義の中で定義された関数です。 メンバー関数の呼出はドット記法で行います。 メンバー関数からは、プライベートなクラスのメンバーにアクセスできます。
クラス

オブジェクトは、匿名クラスの定義とインスタンス化を同時に行うものです。
クラス

クラスは、明示的に継承元を指定しない場合は Any を継承します。
クラス

継承モディファイア( inheritance modifier )には、次のような種類があり、これらのトークンはモディファイア・キーワードです。
クラス

抽象クラス( abstract class )は、抽象メンバー関数( abstract method )だけを持つクラスです。 モディファイア・キーワード abstract は、抽象メンバー関数の定義でも使われます。
クラス

ファイナルクラス( final class )は、継承を禁止したクラスです。 KotlinのクラスはJavaと異なり、ディフォルトで継承禁止なので、継承禁止を強調する意味しかありません。 モディファイア・キーワード final は、オーバーライド禁止メンバーの宣言でも使われます。
クラス

オープンクラス( open class )は、継承を許可したクラスです。 KotlinのクラスはJavaと異なり、ディフォルトで継承禁止なので、継承を行う可能性がある場合は明示的に許可する必要があります。 モディファイア・キーワード open は、メンバー関数のオーバーライド許可でも使われます。
クラス

クラスのメンバー関数が、プロパティやメンバー関数を参照するとき、クラスの外の変数や関数との間で曖昧さが生じる事があります。 このようなときには、インスタンスを表すキーワード this を使います。
クラス

this はこのほか、2 次コンストラクタから同じクラスの別のコンストラクタを呼出すときにもつかわれます。
クラス

クラスモディファイア( class modifier )には、次のような種類があり、これらのトークンはモディファイア・キーワードです。
クラス

列挙型クラス( Enum class )は、有限個の識別子の集合を表現するために使用されます。
クラス

シールドクラス( Sealed class )は、制限されたクラス階層を表現するために使用されます。
クラス

アノテーションクラス( annotation class )は、コードにメタデータを付加するための手段を提供します。
クラス

データークラス( Data class )は、データーを保持するためのクラスで、copy() などのメンバー関数がクラスを定義しただけで生えてきます。
クラス

インナークラス( Inner class )は、入れ子になった内側になったクラスが外側のクラスのメンバーにアクセスすることを可能にします。
クラス

値クラス( Value class )は、イミュータブルなスカラー値の型を定義します。プロポーザル段階では inline class と呼ばれていました。
クラス

+ ラッパークラスとして機能し、型安全性やコードの表現力を向上させます。
クラス

オブジェクト( object )は、モディファイア・キーワードではありませんが、特殊なクラスの一種なので併せて紹介します。 オブジェクトは一過的な匿名クラスを定義し、そのインスタンスの生成を行います。
クラス

各クラスモディファイアは、異なる用途や特性を持っており、柔軟なクラス定義を可能にします。 適切なモディファイアを選択することで、コードの意図を明確に表現し、保守性や可読性を向上させることができます。
クラス

クラス、オブジェクト、インターフェース、コンストラクター、関数、およびプロパティとそのセッターは、可視性モディファイア( Visibility modifiers )を持つことができます。ゲッターは常にそのプロパティと同じ可視性を持っています。
クラス

可視性モディファイアには、次のような4種類があり、これらのトークンはモディファイア・キーワードです。
クラス

デフォルトの可視性はpublicです。
クラス

関数、プロパティ、クラス、オブジェクト、およびインタフェースは、パッケージの中で直接「トップレベル」で宣言することができます。
クラス

クラス内部で宣言されたメンバー。
クラス

protectedまたはinternalメンバーをオーバーライド( override )し、可視性を明示的に指定しない場合、オーバーライドしたメンバーも元のメンバーと同じ可視性を持つことになります。
クラス

クラスの一次コンストラクタの可視性を指定するには、次の構文を使用します。
クラス

ローカル変数、関数、クラスは可視性モディファイアを持つことができません。
クラス

internal 可視性モディファイアは、そのメンバーが同じモジュール内で可視であることを意味します。具体的にモジュールとは、例えば、一緒にコンパイルされたKotlinファイルの集合のことです。
クラス

抽象クラス( abstract class )は、抽象メソッド( abstract method )だけを持つクラスであり、直接のインスタンス化ができません。抽象メソッドは本体を持たず、具体的な実装はそのサブクラスに委ねられます。Kotlinでは、abstract キーワードを使用して抽象クラスと抽象メソッドを宣言します。
クラス

上記の例では、Shape という抽象クラスがあります。このクラスは抽象メソッド draw を宣言しています。サブクラスである Circle と Rectangle は、それぞれ draw メソッドをオーバーライドして具体的な実装を提供します。
クラス

抽象クラスは直接インスタンス化できないため、Shape クラスのインスタンスを作成しようとするとコンパイルエラーが発生します。代わりに、具象サブクラスである Circle や Rectangle のインスタンスを作成して使用します。
クラス

抽象クラスは抽象プロパティを持つこともできます。また、抽象クラス自体はコンストラクタを持つことができます。
クラス

この例では、Shape クラスはコンストラクタを持ち、name という抽象プロパティを宣言しています。サブクラスである Circle と Rectangle は、コンストラクタで name を渡し、draw メソッドをオーバーライドしています。
クラス

抽象クラスは、クラス階層の一部として柔軟で再利用可能なコードを設計する際に役立ちます。
クラス

抽象クラスは、以下のようなユースケースやベストプラクティスに適しています。
クラス

抽象クラスは、柔軟性と再利用性を向上させるために使われますが、適切に設計される必要があります。必要以上に多くの機能を含めると、過度な依存関係が生まれる可能性があるため、慎重な設計が求められます。
クラス

ファイナルクラス(final class)は、Kotlinにおいて継承を禁止したクラスを指します。Kotlinでは、デフォルトでクラスが継承不可(final)となっており、継承可能にするためには明示的にopen修飾子を使用する必要があります。そのため、finalキーワードは主にオーバーライド禁止メンバーの宣言で使用され、クラス自体に適用することは少ないです。
クラス

上記の例では、MyFinalClass はファイナルクラスとして宣言されています。このクラスは他のクラスから継承できません。
クラス

上記の例では、MyBaseClass の myFinalMethod は final 修飾子が付いており、このメソッドはオーバーライドできません。
クラス

上記の例では、Configuration クラスがファイナルクラスとして定義されています。このクラスは他のクラスから継承できないため、設定情報の不正な変更や上書きを防ぐことが期待されます。ApplicationSettings クラスは Configuration を利用してアプリケーションの設定を管理しています。
クラス

ファイナルクラスは特定の状況で利用され、継承を禁止してクラスの拡張を制御するために使用されます。
クラス

オープンクラス(open class)は、Kotlinにおいて継承を許可したクラスを指します。 Kotlinのクラスはデフォルトで継承不可(final)となっているため、クラスを継承可能にするには明示的にopen修飾子を使用する必要があります。
クラス

上記の例では、MyOpenClass はオープンクラスとして宣言されています。このクラスは他のクラスから継承できます。
クラス

上記の例では、MyBaseClass の myMethod は open 修飾子が付いており、このメソッドはオーバーライド可能です。
クラス

上記の例では、Shape クラスがオープンクラスとして定義されています。Circle と Square クラスが Shape を継承し、draw メソッドをオーバーライドしています。これにより、各図形クラスは自身の特定の描画方法を持つことができます。
クラス

オープンクラスは継承を許可し、クラスの拡張やカスタマイズが可能となります。ただし、使用する際には慎重に設計し、必要なメソッドやプロパティに対してのみopen修飾子を使用することが推奨されます。
クラス

列挙型クラス( Enum classes )は、キーワード enum を class に前置して定義します。
クラス

Swift/オブジェクト指向#列挙型の例を Kotlin 向けにモディファイしました。
クラス

シールドクラス(Sealed class)は、制限されたクラス階層を表現するために使用される Kotlin 特有の機能です。シールドクラスは、特定のサブクラスのみを許容し、新しいサブクラスの追加を防ぎます。これにより、特定の型に対するパターンマッチングが容易になります。
クラス

上記の例では、Result クラスはシールドクラスとして宣言されています。このクラスには3つのサブクラスがあります:Success、Error、および Loading。Success と Error はデータクラスで、それぞれデータを保持します。Loading はオブジェクトクラスで、データを保持しません。
クラス

上記の例では、Result クラスのサブクラスごとに異なる処理を行う processResult 関数があります。when 式を使用して、特定のサブクラスに対するパターンマッチングを行っています。
クラス

シールドクラスは、特に固定されたクラス階層を表現する場合や、特定の型に対する安全なパターンマッチングを行う場合に便利です。
クラス

アノテーションクラス(annotation class)は、Kotlinにおいてコードにメタデータを付加するための手段を提供します。これにより、コンパイラや実行時の処理で追加の情報を提供することが可能となります。
クラス

アノテーションクラスは、@シンボルを使って宣言されます。アノテーションクラスの主な目的は、アノテーションを作成し、それをコードの要素に適用することです。
クラス

上記の例では、MyAnnotation というアノテーションクラスが宣言されています。このアノテーションは、name と version というパラメータを持っています。
クラス

アノテーションは、クラスや関数、プロパティなど、さまざまな要素に適用できます。
クラス

上記の例では、MyClass クラスとその中の myFunction 関数に MyAnnotation が適用されています。これにより、このクラスや関数に対する追加のメタデータが提供されます。
クラス

アノテーションをプロセッシングするためには、リフレクションやKotlinのアノテーションプロセッサを使用することがあります。これにより、アノテーションに関連する処理を行うカスタムロジックを実装できます。
クラス

上記の例では、AnnotatedElementを受け取り、その要素に MyAnnotation が適用されているかを調べ、情報を取得しています。
クラス

アノテーションクラスは、コードにメタデータを追加し、プロセッシングや設定などの目的で使用されます。
クラス

データークラス(Data class)は、Kotlinにおいてデータの保持や操作を目的としたクラスで、copy() メソッドなどがクラスを定義するだけで自動的に生成されます。これにより、不変性やイミュータビリティ(immutable)を維持しながら、簡潔で効果的なデータクラスを作成できます。
クラス

上記の例では、Person クラスがデータークラスとして宣言されています。コンストラクタで定義されたプロパティ(name と age)に対して、equals()、hashCode()、toString() などの標準メソッドが自動的に生成されます。
クラス

上記の例では、equals() メソッドにより person1 と person2 の内容が一致するか比較され、toString() メソッドによりクラスの内容が文字列として表示されます。また、copy() メソッドを使って一部のプロパティを変更した新しいインスタンスを作成しています。
クラス

データークラスが生成される主なメソッドは以下の通りです。
クラス

データークラスは、イミュータブルでありながら効果的にデータを操作するための便利な手段を提供します。
クラス

Kotlinのインターフェース(interface)は、抽象的なメソッドの宣言と、メソッドの実装を含むことができます。インターフェースは、抽象クラスと異なり状態を保持することができません。プロパティを持つ場合、これらは抽象クラスであるか、アクセサーの実装を提供する必要があります。
クラス

上記の例では、MyInterface インターフェースが、抽象メソッド doSomething() とデフォルトのメソッド doSomethingElse()、抽象プロパティ property を宣言しています。
クラス

上記の例では、MyClass クラスが MyInterface インターフェースを実装しています。doSomething() メソッドと property プロパティをオーバーライドしています。
クラス

上記の例では、C クラスが A インターフェースと B インターフェースの両方を実装しています。複数のインターフェースをカンマで区切って指定することができます。
クラス

上記の例では、D インターフェースが A インターフェースと B インターフェースを継承しています。これにより、D インターフェースは A と B のメソッドを含むことになります。
クラス

Kotlinのインターフェースは、クラスが異なる振る舞いを持つ場合に簡潔で柔軟な解決策を提供します。異なるインターフェースを実装することで、複数の振る舞いを同じクラスで組み合わせることができます。
クラス

インナークラス(Inner class)は、入れ子になった内側のクラスが外側のクラスのメンバーにアクセスすることを可能にします。これにより、外側のクラスと強い結びつきを持ちながら、内部で独自の振る舞いやデータを持つクラスを定義できます。
クラス

上記の例では、OuterClass という外側のクラスがあり、その中に InnerClass というインナークラスが定義されています。InnerClass は OuterClass のプロパティにアクセスすることができます。
クラス

上記の例では、OuterClass のインスタンスを作成し、そのインナークラスである InnerClass のインスタンスを取得しています。そして、InnerClass のメソッドを呼び出して外側のクラスのプロパティにアクセスしています。
クラス

インナークラスは、外部クラスとの緊密な連携が必要な場合や、外部クラスのプライベートなメンバーにアクセスする必要がある場合に有用です。
クラス

値クラス(data class)は、イミュータブルでスカラーな値の型を定義するための概念です。プロポーザル段階では inline class と呼ばれていました。値クラスは、プリミティブ型のように振る舞い、同時に型安全性を提供します。
クラス

上記の例では、Email という値クラスが宣言されています。この値クラスは、イミュータブルであり、value というプロパティを持っています。
クラス

上記の例では、異なるインスタンスの Email クラスを作成し、その値が等しいかを比較しています。値クラスでは、プライマリコンストラクタの引数で値が確定し、その値に基づいて等価性が判定されます。
クラス

値クラスは、ドメインモデリングや特定のデータ型を表現する際に有用であり、プロジェクト全体でのコードの理解性や保守性を向上させる役割を果たします。
クラス

オブジェクト(object)は、モディファイア・キーワードではありませんが、特殊なクラスの一種であり、一過的な匿名クラスを定義し、その唯一のインスタンスを生成します。オブジェクトはシングルトンのような振る舞いを持ち、一般的には特定の目的に使用されます。
クラス

上記の例では、Logger という名前のオブジェクトが宣言されています。このオブジェクトはシングルトンであり、log メソッドを持っています。
クラス

上記の例では、Logger オブジェクトの唯一のインスタンスにアクセスし、その log メソッドを呼び出しています。オブジェクトは初回のアクセス時に遅延初期化され、以降は同じインスタンスが再利用されます。
クラス

オブジェクトは特定のタスクや目的に対して唯一のインスタンスを提供する場合に利用され、例えばロギングや設定の管理などに適しています。
ジェネリックス

ジェネリックス( Generics )とは、汎用的なクラス・関数やメソッドを特定の型に対応づける機能のことです。
キーワード一覧

Kotlinのキーワード( Keywords )は
キーワード一覧

に分類されます。
キーワード一覧

以下のトークンは、常にキーワードとして解釈され、識別子として使用することはできません。 このようなキーワードをハード・キーワード( Hard keywords )と呼びます。
キーワード一覧

以下のトークンは、それが適用される文脈( context )ではキーワードとして機能し、他の文脈では識別子として使用することができます。 このようなキーワードをソフト・キーワード( Soft keywords )と呼びます。
キーワード一覧

アノテーション使用側ターゲット( Annotation use-site target )は、Kotlinにおいてアノテーションが特定の要素に対して適用される位置を指定する構文です。これにより、生成されるJavaバイトコードにおいてアノテーションがどの要素に適用されるかを正確に指定できます。
キーワード一覧

以下は、一般的なアノテーション使用側ターゲットの指定方法です。
キーワード一覧

これらの使用側ターゲットを使うことで、アノテーションが生成される場所を明確に指定することができ、柔軟性を保ちつつ、正確な挙動を得ることができます。
キーワード一覧

以下のトークンは、宣言の修飾語リスト( modifier lists of declarations )のキーワードとして機能し、他のコンテキストでは識別子として使用することができます。 このようなキーワードをモディファイア・キーワード( Modifier keywords )と呼びます。
キーワード一覧

以下の識別子は,コンパイラーが特定の文脈で定義したもので、他の文脈では通常の識別子として使用することができます。 このような識別子を特殊識別子( Special identifiers )と呼びます。
キーワード一覧

Kotlinは以下の演算子( Operators )や特殊特殊シンボル( special symbols )をサポートしています。
Kotlin標準ライブラリー

Kotlin標準ライブラリー( Kotlin Standard Library )は、以下のような機能を提供します。
Kotlin標準ライブラリー

Kotlin標準ライブラリーはKotlin自身で書かれています。
Kotlin標準ライブラリー

kotlin.annotation.*
Kotlin標準ライブラリー

Kotlinには、Arrayから始まり、Iterable, Collection, List, Set, Mapなどのコレクション型が豊富に用意されています。これらは主に kotlin.collections パッケージで提供されており、ディフォルトインポートなので追加のインポートなしで利用できます。
Kotlin標準ライブラリー

Iterable インターフェースは、Kotlinの標準ライブラリで使用される反復可能なコレクションの基本的なインターフェースです。このインターフェースは、コレクションが要素の反復処理を可能にするために必要な機能を提供します。
Kotlin標準ライブラリー

以下に、Iterable インターフェースの主な要素と使用法を示します:
Kotlin標準ライブラリー

Iterable インターフェースは、Kotlinでコレクションを扱う際に非常に重要であり、様々な反復処理操作を可能にします。
Kotlin標準ライブラリー

Collection インターフェースは、Kotlinの標準ライブラリで提供されるコレクション型の基本インターフェースの一つです。このインターフェースは、複数の要素を保持するデータ構造を表現し、それらの要素に対する基本的な操作を提供します。
Kotlin標準ライブラリー

以下に、Collection インターフェースの主な特徴と使用法を示します:
Kotlin標準ライブラリー

Collection インターフェースは、Kotlinのコレクションの基本的な機能を提供し、様々な種類のコレクションがこれを実装しています。これにより、異なる種類のコレクションを一貫して扱うことができます。
Kotlin標準ライブラリー

Listは、要素数が固定で要素の値を変更できないコレクションです。
Kotlin標準ライブラリー

上記の例では、ArrayList を使ってListを生成しています。ArrayListは要素の順序が保持され、可変長の動的な配列を表現します。add メソッドを使用して要素を追加することができます。
Kotlin標準ライブラリー

mutableListOf() を使って MutableList を生成し、add メソッドを使用して要素を追加しています。MutableListは要素の変更が可能なListです。
Kotlin標準ライブラリー

これらの例から分かるように、Kotlinのコレクションは型安全で、読み取り専用と可変なコレクションの違いが明確になっています。リストの他にも、SetやMapも用意されており、それぞれの特徴に応じて適切なものを選択できます。
Kotlin標準ライブラリー

kotlin.collections パッケージのコレクションクラスや関連機能は、さまざまなプログラミングシナリオで利用されます。以下は、kotlin.collections の主なユースケースのいくつかです:
Kotlin標準ライブラリー

以下は、これらのユースケースの簡単な例です:
Kotlin標準ライブラリー

これらの例は一部の機能を示すものであり、kotlin.collections のコレクションは、さまざまなプログラミングニーズに対応する強力なツールセットを提供します。
Kotlin標準ライブラリー

kotlin.collections を使用する際のベストプラクティスはいくつかあります。以下にいくつか挙げてみましょう:
Kotlin標準ライブラリー

これらのベストプラクティスは、コードの品質、パフォーマンス、保守性を向上させるのに役立ちます。使用ケースによって最適なアプローチを選択することが重要です。
Kotlin標準ライブラリー

kotlin.comparisons.*
Kotlin標準ライブラリー

kotlin.io.*
Kotlin標準ライブラリー

kotlin.ranges.*
Kotlin標準ライブラリー

kotlin.sequences.*
Kotlin標準ライブラリー

kotlin.text.*
Kotlin標準ライブラリー

[TODO:Rangeはコレクションではないので再分類が必要]
Kotlin標準ライブラリー

println((1..5).javaClass.kotlin)の結果が示す通り、範囲リテラル1..5はclass kotlin.ranges.IntRangeです。 コレクションは、Ranges以外にも、Sequences・Ranges・Lists・Arrays・Sets・Mapsなどがあります。これは網羅していませんし、上記の forプロトコルに従ったクラスを作れば、ユーザー定義のコレクションも作成できます。
Kotlin標準ライブラリー

Kotlinの標準ライブラリーにあるrepeat関数は、定数回の繰返しが必要な時に便利です。
Kotlin標準ライブラリー

repeat関数もそうですが、Kotlinにはブロックを受取る関数(やメソッド)があります。
Kotlin標準ライブラリー

このように、ブロックを取るメソッドを使うとコレクションに関する操作を簡素に書けます。
Coroutine

Kotlinは、言語レベルでコルーチンをサポートし、機能の大部分をライブラリに委ねることで、この問題を柔軟に解決しています。
Kotlin Script

Kotlin Script では、.jar を生成せず、そのままコードが実行されます。 また、main 関数をエントリーポイントはぜず、スクリプトの書かれた順に評価します。
Kotlin Script

ビルドツールの Gradle では、従来は Groovy がビルド構成ファイルに使われていましたが、Kotlin Script への移行が進んでいます。