はじめに
JavaでもKotlinでも作成出来るAndroidプログラムですが圧倒的にKotlinの資料が~~~ありません~~~なかなかありません。困ったときに検索しては覚えていくのではキリがありません。
こういうときにリファレンスマニュアルがあればプログラムを作りながら調べることが出来るのですが2020年現在Kotlinにリファレンスマニュアル~~~はありません~~~ほとんどありません。
仕方が無いのでせめて自分用としても役に立つようなリファレンスマニュアルをQiitaで作っていきたいと思います。
1箇所に全てを記述すると読みづらいため、最初はここに直接書いていきますが、ある程度情報が蓄積できたらここをインテックスとして説明をリンクしていく形にしたいと思っています。
基本は自分用ですが初心者のため指摘があると助かります。
型
数値
基本となる**数値型(整数)**は下記のようになっています。
型名 | ビット数 |
---|---|
Int | 32 |
Long | 64 |
Short | 16 |
Byte | 8 |
浮動小数型は下記の様になっています。
型名 | ビット |
---|---|
Float | 32 |
Double | 64 |
文字
文字はChata型を使用します。数値でも8ビットでも無いことに注意です。
文字列はString型を使用します。
真偽
真偽はBoolean型を使用します。真偽値はtrueかfalseのどちらかが入ります。
日付型と時刻型
日付はLocalDate型を時刻はLocalTime型を、その両方を同時に扱う日時はLocalDateTime型を使います。
宣言
Kotlinは
var 変数名 : 型 = 初期値
val 変数名 : 型 = 初期値
というように宣言します。
varは可変の変数でvalは不変(値固定)の変数宣言になります。
基本的に宣言時には初期値を代入します。
値の書き方として整数の数値の場合は
val bin : Int = 0b0001100 // 2進数の1100 つまり 10進の12が入る
val hex : Int = 0x20 // 16進の20H つまり 10進の32が入る
このような代入が使えます。
浮動小数点型の場合は
val d: Double = 2.0 // 2と書いたらエラー
val f: Float = 2F // 2と書いたらエラー
のように明示的に型を示す数値を扱う必要があります。
文字、文字列の場合は
val c: Char = "c"
val s: String = "str"
のように記述します。
文字列の代入の記述(リテラル)には特殊な方式もありますが後術します。
ヌル許容型
変数の型ではありませんが、ヌル許容型というのがあります。例えば
t = null;
for (i = 0;i < 10;i++){
if(tbl[i] == 1) t = tbl[i];
}
t.get();
言語が適当ですが、ループ内で値が決まる処理などで値が決まらない場合もあります。
しかし t.get() といきなり呼び出してしまうと t は null の場合もあるのでエラーになります。
これを改善するには
t = null;
for (i = 0;i < 10;i++){
if(tbl[i] == 1) t = tbl[i];
}
if (t != null) t.get();
nullかどうか比較する必要があります。しかしAndroidの世界では非常に多数のnullが発生する要因があり、その旅にnullと比較するとキリがありません。
そのような事情を察してかKotlinには便利なヌル許容型があります。
ヌル許容型は変数宣言の時に変数の型の最後に**?**を付けるだけです。
Kotlinでそれっぽく置き換えると
t : Test? = null
for (i in 0..9){
if(tbl[i] == 1) t = tbl[i]
}
t?.get()
となります。if分が?に置き換わっただけで文字数はともかく行数は変わらないと感じますが入れ子式にヌル許容型を利用することも出来ますので便利になります。
ヌル許容型の最低限の例を下記に示します。
var i : Int = null // NG
var i : Int? = null // OK null代入はヌル許容型であること
var i : Int? = null
var j : Int = i // NG null許容型の代入先はnull許容型
var j : Int = i!! // OK null許容型から普通の型への代入時は!!を使う。
Javaとの比較
Javaを触ってないから DelphiやLazarusとの比較は出来るけど意味を感じない。
定数
元々変数の定義にvalがあるのでわざわざ定数定義は不要では無いか?と思いますが
const val x : Int = 1
val y : Int = 1
print x // print 1 と同様
print y // fun gety(){ return 1} gety() と同様
と内部でメソッド化が行われているので違いが発生します。
変数の命名規則
Kotlinの変数や関数(メソッド)の命名規則は基本的にJavaの命名規則に沿ったものとなります。
・外部からアクセス可能な変数は先頭小文字、2番目の単語からは単語ごとに先頭を大文字でアンダースコア ( __ ) は使わない。
・外部から定義可能なクラスは先頭大文字、上記と同様に2番目の単語からは単語ごとに先頭を大文字でアンダースコア( __ )は使わない。
・定数は全て大文字、単語の区切りはアンダースコア"__"を使用する。
ローカル(プライベート)なものは命名規則がありませんが、プライベートクラスや変数を使用する場合はそのクラス名やプライベート変数の元になるグローバル変数にmを付けるものが多数存在します。
val mTestClass = TestClass()
var index : Int
private var mIndex : Int
型変換
よく使用される数値型と文字列型の変換方法は
val str : String = "123"
val i : Int = 456
str.toInt() // String -> Int 変換
i.toString() // Int -> String 変換
このようになります。
配列
Array
Kotlinに触れてみてもっとも迷ったのが配列です。種類が無駄に多く定義も使用方法も難解です。
とりあえずC言語のサンプルを
int tbl[10];
int i;
for (i = 0; i < 10; i++) {
tbl[i] = i;
}
値が10要素入るint型の配列を作って tbl[0] = 0 と添え字の値をそのまま中身にしてしまおうというサンプルです。これをKotlinで書くと
var tbl = IntArray(10)
for (i in 0..9){
tbl[i] = i
}
IntArrayがInt型の配列を示していることがわかります。ということは他の型もありそうですね。
他の書き方もあります。
var tbl : Array<Int> = Array(10){0}
for (i in 0..9){
tbl[i] = i
}
ループ変数iの定義を忘れていますよと他言語から指摘されそうですがこれは通ります。
ループ部分は変わらないですが定義が・・・何これ状態です。
Int型の配列定義としてArrayがそうなのでしょうが右辺が意味不明です。Array(10)が要素数・・・でしょうか?その右の{0}って・・・
これ0で初期化を表しています。C言語でも初期値指定はありますので納得するとして {}が突然出てきます。
これ初期化ですが初期化時に{}内の処理が働きます。
そんな馬鹿な!?と思いますが上記の4行が1行で書けたりします。
var tbl : Array<Int> = Array(10){it}
変数宣言を書いていたつもりがいつの間にか値を代入するプログラムを書いていた!
{}内は処理なので
var tbl : Array<Int> = Array(10){it * 2}
0 2 4 と入れようと思ったらこう書けばいいわけです。
List
ListもArrayと同じよう使えます。
var tbl = List(10){it}
違いは代入出来ないことです。定数定義配列のときは使いそうです。
var で定義しても変更出来ないことに注意しましょう。
MutableList
Listを値の変更に対応させたMutableListというのもあります。
var tbl = MutableList(10){it}
Listをわざわざ変更可能にして使うならArray使うわ、となりそうですがListにしかない機能があります。