Kotlin とは?
- 型推論のある静的型付けのOBJ指向言語
- Javaとの連携が言語仕様に存在。KotlinからJavaのクラスやメソッドを呼べたりもする
オンライン実行環境
以下の本家サイトの実行環境で、実際に試しながら学習を進めると捗ります。
Kotlin Playground: Edit, Run, Share Kotlin Code Online
- 文末のセミコロンが不要
- 型
- 参照型しかない
。プリミティブ型はない
- val:読み出しのみ、var:読み書き可
- 定数:const。const val MAX_NUM = 10
null関係
nullチェックなしコードはコンパイル時にエラー
var a: String = "moji"
a = null
var a: String? = "moji"
a = null
nullじゃないとき実行する
var str: String? = null
str?.split(",")
nullじゃないとき値設定(エルビス演算子)
Company.setName(name?: "ななしの会社")
スコープ関数
hoge?.let {
textView.text = it.name
}
他にrun, also, applyなどが存在。おいおい理解していく。
値比較、参照比較
val value1 = "a"
val value2 = "b"
if (value1 == value2) // 値比較で false。否定は !=
var list1 = listOf(1,2,3)
var list2 = listOf(1,2,3)
if (list1 === list2) // true =が3つ。javaは== だったので間違えないように
文字列
文字列中に埋め込み文字
var shopName: String = "sevene"
println("${shopName}")
println("$shopName")
改行入り文字列
行頭の| は目印の記号。trimMarginで除去可能
fun main(args: Array<String>) {
var strStory = """
|本日は
|晴天なり
|明日もそうなる
""".trimMargin()
println("$strStory")
}
型
キャスト
val hoge = obj as Hoge
関数 function
基本の書き方
fun strConbine(a: String, b: String): String {
return a + b
}
fun strConbine(a: String, b: String): = return a + b
fun strConbine(a: String, b: String): Unite {
println(a + b)
}
名前付き引数
引数が多いかつ、同じ型の場合、どの項目に設定しているのか間違えやすい場合がある
その場合に値設定時にあえて関数側の引数名をあえて指定して関数を呼び出す書き方です。
JavaではBuilderパターンを使って回避したりするが、いかんせんコード量が増えがち。
class Book(
val title: String,
val price: Int,
val author: String,
val isbn: String,
val remarks: String
) {
override fun toString(): String {
return "Book(title='$title', price=$price, author='$author', isbn='$isbn', remarks='$remarks')"
}
}
呼び出し側のコードは以下です。
val book = Book(
title = "Kotlinイン・アクション",
price = 4115,
author = "Dmitry Jemerov",
isbn = "978-4839961749",
remarks = "サイズ: 23.6x18.2x3.6 cm")
println(book)
関数オブジェクト
fun main() {
val function = ::func
println( function() )
val function2: () -> String = ::func
println( function2() )
}
fun func(): String {
return "test"
}
fun main() {
val square: (Int) -> Int = { i: Int -> i * i }
val square2: (Int) -> Int = { i -> i * i }
val square3 = { i:Int -> i * i }
val square4: (Int) -> Int = { it * it }
}
制御文
if
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
for
for (i in array.indices)
print(array[i])
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
for (i in list.orEmpty()) {
}
while
while (x > 0) {
}
配列、コレクション
配列
val list = arrayOf(1, 2, 3)
val list = intArrayOf(1, 2, 3)
println(list[0])
for(item in list){
println(item)
}
コレクション
val list = listOf(1, 2, 3)
val list = mutableListOf(1, 2, 3)
val list = mutableListOf<TMP>()
val list = setOf(1, 2, 2, 3)
val map = mapOf(
1 to "one",
2 to "two",
3 to "three"
)
for(item in map)
println("${item.key} to ${item.value}")
for((key, value) in map)
println("${key} to ${value}")
クラス
データクラス
データのみを保持するクラスは、classの前にdataを付与して宣言
data class User(val name: String = "", val age: Int = 0)
val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)
val jane = User("Jane", 35)
val (name, age) = jane
data class User(val name: String = "", val age: Int = 0) {
constructor(name: String, age: Int, email: String) : this(name, age)
}
コンパニオンオブジェクト
class MyClass {
companion object {
const val FREE_PRICE = 0
fun hello(greeting: String) { println(greeting) }
}
object {}
}
fun MyClass.Companion.foo() {
println("hoge")
}
fun main(args: Array<String>) {
MyClass.Companion.foo()
MyClass.foo()
}
通常クラス
class Hoge {
var name: String = ""
constructor(name: String) {
this.name = name
}
fun printMethod(strPrint: String) {
println(strPrint)
}
}
class Hoge(n: String) {
val name = n
}
class Hoge(val name: String) {
}
継承
open class Base {
}
class Hoge : Base() {
}
インターフェース
interface Hoge {
fun hoge()
}
class Sample: Hoge {
override fun hoge() {
println("hogehoge")
}
}
class Sample {
private val h = object: Hoge {
override fun hoge() {
println("hogehoge")
}
}
}