kotlinのデータ型・型推論・null・コレクション


kotlinのデータ型と型推論、nullの扱い、コレクションについて簡単にまとめました。


## データ型
#### 1.整数
```kotlin:整数
var hoge = 30//この時点でhogeは勝手にint型になってる
//int型以外のものは代入できない
hoge = "hogehoge"//Type mismatch: inferred type is String but Int was expected で怒られる

//データ型一覧
//整数
val num1: Int = 10 //　32bit
val num2: Long = 10 //　64bit
val num3: Short = 10 //　16bit
val num4: Byte = 10 //　8bit

//型指定を省略した場合はInt型に推論される
var hoge = 30//これはInt型

//ちなみに以下のようにサフィックスをつけるとLong型になる
var hoge = 30L//これはLong型になる


```
#### 2.小数
``` kotlin:小数
val num1:Double = 1.0 // 64bit
val num1:Float = 1.0F // 32bit

//型指定を省略した場合はDouble型に推論される
val num1= 1.0 // これはDouble型になる

```
#### 3.符号なし整数
``` kotlin:符号なし整数
//unsignedのUを型指定の手前と代入数値の後につけることで符号整数にできる
val num:UByte = 255U
```

数値だけでこんなにもある

#### 4.文字列と文字
```kotlin:文字列
val str: String = "hello"//文字列を格納できる
val ch:Char = 'S'//一文字だけ 
//charはUnicode文字を格納するので漢字を代入してもOK！
```


#### 5.真偽値
```kotlin:真偽値
val bool:Boolean = true
```

#### 6.Any
```kotlin:Any
var any:Any =10

any = "hello"//これが許容される
```
Anyに頼らない人生を送りたいですね


## 型変換メソッド
以下のように型変換を行うことで異なる型の値を代入することができる

```kotlin:型変換メソッド
//以下のような異なる方への代入はできない
val x: Int = 100
val y: Long = x


//以下のように型変換を行うことができる
val a: Int = 10
val b: Long = a.toLong() //ここでLong型に型変換される

val c = 1.9
val d:Int =c.toInt() //小数点以下が切り捨てられる
println(d) // => １　


```

## null許容型・非許容型
これまでの変数宣言の方法は全てnull非許容型でした。
変数の型にはnull許容型・非許容型の２種類あります。
nullの扱いについてのまとめです。
#### セーフコール演算子
型の後にセーフコール演算子である「？」をつけることでnull許容型として宣言できます
```kotlin: null許容型
val str: String? = null
```
セーフコール演算子はメソッドの実行時にも使用されます
```kotlin:メソッド
val str:String? = null
println(str.length) //strはnull許容型のためエラーになる
println(str?.length) //strはセーフコール演算子により実行が許可される。結果はnullになる
```
#### エルビス演算子を使う　
nullだった場合違う値に変換したい時はエルビス演算子「?:」を使用する
```kotlin:エルビス演算子
val str:String? = null
println(str?:"".length)//=>0
//strがnullなので空文字に変換される
```

#### スマートキャストで自動的に型変換を行う
```kotlin:スマートキャスト

val list:MutableList<Int>  = mutableListOf(10,20,30) //listを作成
val num: Int? = list.min()//list内の最小値を格納。listの値がない場合はnullが格納される。

//ダメな例
print(num * 2) //null許容型に対して算術演算子は使用できない

//スマートキャストを使用した例
if(num != null){
//このブロック内ではnumはnull非許容型に変換される
println(num * 2)//問題なく動く
}
```
スマートキャスト面白いですね！

#### 「!!」でnull許容型　→　null非許容型に変換する
　!!は「not-null assertion」って言うらしい
nullが入る可能性のあるものには使用しないこと。
```kotlin: !!
val name:String? = getName()//どこからか名前を取得するメソッドを実行
val nameLength = name!!.length//！！を記述することで非null型に強制変換
//対象の値に誤ってnullが混ざり込んだ場合は「KotlinNullPointerException」のエラーで怒られる

```

## 配列・リスト・セット・マップ
配列・リスト・セットは、データを格納するために使用される4つの主要なコレクションタイプです。

#### 配列
 配列は、固定長のデータのシーケンスを格納するために使用されます。配列は、インデックスによってアクセスでき、順番も保持されます。
配列の長さを後から変更することはできません。
```kotlin: 配列
val array:Array<Int> = arrayOf(10,20,30)
println(array[0]) // => 10

val array1:IntArray = intArrayOf(10,20,30)//こうやってint型の配列の宣言もできる
val array2:doubleArray = doubleArrayOf(10.0,20.0,30.0)//double型の配列の宣言もできる

val array3 = arrayOfNulls<String>(5)//初期値がnullの配列。後々入る値の型を指定する必要がある。
array３.forEach { println(it)} //array３の中身を全てprint => null が５つ表示される。
```


#### リスト
　リストは、可変長のデータのシーケンスを格納するために使用されます。Listはインデックスによってアクセスでき、順番も保持されます。
配列はと異なり後から長さを変えることができます
デフォルトではimmutable(変更不可)なので注意

```kotlin:リスト
//変更不可のリスト
val list :List<Int> = lilstOf(10,20,30)
println(list[0]) //=> 10
//list[0] = 11 //これはエラーになる

//変更可のリスト
val list2 :List<Int> = mutableLilstOf(10,20,30)
println(list2[0]) //=> 10
list2[0] = 11 //OK
println(list) //=> [10,20,30]

//要素の追加
list2.add(40)
println(list2) //=> [10,20,30,40]

list2.add(0,1) //０番目の要素に1を追加
println(list2) // =>[0,10,20,30,40]

//list.add(40)  //listはimmutableなのでエラーになる

//要素の削除
list2.removeAt(4) //要素のindexを指定して削除する
println(list2) //=> [0,10,20,30]
list2.remove(20) //要素の値を指定して削除(重複要素がある場合はindexの小さい方のみ削除される)
println(list2) //=> [0,10,30]

//list.remove(10)  //同じくlistはimmutableなのでエラーになる
```
#### セット
　セットは、重複しない要素の集合を格納するために使用されます。Setは、インデックスによってアクセスされず、順番は保持されません。
また重複は許可されません。デフォルトではimmutable(変更不可)なので注意

```kotlin:セット
val set = mutableSetOf(10,20,30)
println(set) //=> [10,20,30]

//要素の追加
set.add(40) //indexの指定はできない
println(set) //　=> [10,20,30,40]

set.add(40) //重複を許可しないがエラーも起きない
println(set) //　=> [10,20,30,40]

//要素の削除
set.remove(30) //indexの指定はできないので要素で指定
println(set) //=> [10,20,40]
```


#### マップ
　マップはキーと値の組み合わせを格納するために使用されます。 Mapは、キーによってアクセスでき、順番は保持されません。
値の重複は許可されるがキーの重複は許可されません。デフォルトではimmutable(変更不可)なので注意


```kotlin:マップ
val map = mutableMapOf<String,String>(
    "apple" to "アップル"
    "banana" to "バナナ"
)
//変更
map["apple"] = "りんご"
println(map) //=>{apple=りんご、banana=バナナ}

//追加
map["orange"] = "オレンジ"//存在しないキーを指定して値を代入する
println(map) //=>{apple=りんご、banana=バナナ,orange=オレンジ}


//削除
map.remove("orange") //削除したいキーを指定する
println(map)// =>{apple=りんご、banana=バナナ}
```


## まとめ
覚えることが多いですが基本をしっかり抑えていきたいですね。
javaScriptにはあまりないnullの扱いが特に慣れないですがスマートキャストとか面白そうなんで
もうちょっと深掘りして記事にできたらなと思います。

間違い等あればご指摘お願いします。