2017年6月21日水曜日

Kotlinを思い出すためのサンプルソース

(2017/06/21)
↑今回から日付を入れます。

仕事ではあまり触れる機会が少ないKotlin。
JavaやPHPの後だと忘れがちなんでそのまま実行できるような
Kotlin思い出す用のソースを貼っておきます。
あとで綺麗に見えるように編集するかも。→しました(2017/06/22。ただしKotlinには対応してないんでハイライトがない。。。)

fun main(args: Array<String>) { // ←JVM言語ですが、このように一番外枠がClassでなくても大丈夫。Ptyhonのモジュールのような考え方です。

    // Javaと相互互換を保証しています。ので、Javaの資産がそのまま使えます。またこのファイルのメソッドなどもJavaから呼び出せます。
    println(java.sql.Timestamp.valueOf("2013-10-11 12:13:4"))
    System.out.println("Javaによるsysout")

    // (アドレスが)変更できない変数の宣言は「val」(Javaで言う所のfinal)
    val str: String = "Hello, World!"
    val num: Int = 5 // プリミティブはない。IntとかLongとか。Javaでいうラッパーを使用する。ここらへんもPythonに近いですね。

    // 3項演算子の代わりにこんな文法がある
    val res = if (num.equals(5)) {
        "Hi, Tom!"
    } else {
        "Hi, Bob!"
    }

    println(str + num.toString())
    println(res)

    // (アドレスが)変更できる変数の宣言は「var」。Kotlinでは可能な限り「val」を使うことを推奨
    var str2: String = "test"
    str2 = "test2"
    println("str2:" + str2)
    val str3: String = "test"
    // str3 = "test3" ←これはコンパイルエラー。リテラルはアドレスが別になるため。
    // str3 = str3 + str2 ←よってこれもコンパイルエラー。StringBuilderのように使う場合はvarを使用する。
    str2 += "abcd"
    println("文字列の変更。test2 + abcd = " + str2)

    // 型の変換は変換元のメソッドで行う
    val int1: Int = "123".toInt()
    val int2 = int1 * 10
    println(int2.toString())
    //Int.parseInt("123") ←こんなメソッドはない

    // Switchはなくて、whenを使う
    val color: String = "青"
    val piyo = when (color) {
        "青" -> "blue"
        "赤" -> "red"
        else -> "other"
    }
    println(piyo)


    // (中身を)変更できないリスト。Pythonで言う所のタプル。
    // (豆知識)Pythonでも可能な限りリストではなくタプルを推奨してますよね。
    println("変更できないリスト")
    val list: List<String> = listOf("1", "2", "5")
    // list.add("5") ←変更できないリストなのでaddメソッドは存在しない
    for (value1 in list) {
        println(value1)
    }

    // (中身を)変更できるリスト。Pythonで言う所のリスト
    println("変更できるリスト。宣言は「val」なところに注目。この場合はアドレスが変わらないという意味")
    // JavaでfinalのListにもaddはできますよね
    val mutableList: MutableList<Int> = mutableListOf(9, 8, 7, 6, 5)
    mutableList.add(4)
    for (value1 in mutableList) {
        println(value1)
    }

    // JavaのObjectにあたるクラスはAnyです
    val any1: Any = "This is Any."
    val any2: Any = 123 // Javaと違ってプリミティブがないのでこんな書き方になる。Javaなら「Object any2 = new Integer(123);」とか。
    println(any1.toString())
    println(any2.toString())

    // クラスの使い方。Kotlinでは「new」は不要
    val carol = Car(price = 1000000, speed = 250, name = "キャロル")
    println("name:" + carol.name) // ←実はこれはフィールド(値)を直接参照しているのではなく、プロパティ(getter)の呼び出しです
    // メソッド呼び出し
    carol.displayInfo()

    // Try-Catch
    try {
        throw Exception("try-catch")

    } catch (e: Exception) {
        println("Error Message:" + e.message)
    }

    // ラムダ
    val sum: (Int, Int) -> Int = { x, y -> x + y }
    println("ラムダの処理結果→" + sum(1, 2))

    // 匿名関数
    val sum2 = fun(a: Int, b: Int): Int {
        return a + b
    }
    println("匿名関数の処理結果→" + sum2(1, 2))

    // 2つの結果を戻してくれる関数。Javaに欲しかったですよね。
    val pair = carol.addNumbers(2, 3)
    println("2つの結果を返してくれる関数 ひとつめ→" + pair.first + " ふたつめ→" + pair.second)

    // プライマリコンストラクタの動き
    val cb400sf = Bike("CB400SF", 200, 800000)
    println("プライマリコンストラクタで設定されたもの→" + cb400sf.name + "," + cb400sf.maxSpeed + ",\\" + cb400sf.price)

    // filterの使い方。trueの要素だけ返す
    val filterSample = arrayOf(1, 2, 3).filter { num -> num != 2 }
    print("filterの使い方→")
    for (x in filterSample) {
        print(x.toString() + " ")
    }
    println()

    // filterNotにすると逆になる
    val filterNotSample = arrayOf(1, 2, 3).filterNot { num -> num != 2 }
    print("filterNotの使い方→")
    for (x in filterNotSample) {
        print(x.toString() + " ")
    }
    println()

    // forEach
    println("ListのforEachはJava8と同じ雰囲気で。")
    listOf(1, 2, 3).forEach { x -> println(x + 1) }
    // リスト系は他にもMaxとかMinとかDistinctとか便利なのがたくさんある。リファレンスは見たほうがいいです。

    // Stringの便利な機能やメソッド
   println("Stringの便利な機能やメソッド")
    val a = 2
    val b = 3
    // もうformatメソッドは必要ありません
    println("$a + $b = ${a + b}") // 2 + 3 = 5
    // ヒアドキュメントも使えます
    val hereDoc = """
<html>
    <body>
        $a + $b = ${a + b}
    </body>
</html>
"""
    println(hereDoc)


    // Kotlinはnull safetyです。
    // 基本的にNull Pointer Exceptionは発生しません。(Javaで定義したメソッドの使い方によってはそれでも起こるけど)
    // 普通の変数にnullを代入しようとするとコンパイルエラーになります
    // val nullDesu: String = null ←コンパイルエラー
    // nullが入り得る場合は明示的に下記のようにしなければいけません
    val nullDesu: String? = null
    // println(nullDesu.length) ←わざとぬるぽ起こそうとしてもコンパイルエラー。nullが入り得る変数で危険なことはできない仕様です
    if (nullDesu != null) {
        println(nullDesu.length) // nullチェックをするとコンパイルが通ります
    }

    // 既存のクラスに機能を追加できる「Extension」という機能
    // 今回はStringクラスに機能追加しちゃいます
    fun String.addShimasu(x: Int): String {
        return this + x.toString()
    }
    println("これがExtensionです!!!".addShimasu(123456))

}

// クラスの書き方(Javaっぽく) 
// ちなみにデフォルトだとclassはpublic finalです。
// また、staticの概念はないです
class Car {
    // getterやsetterは記載不要です。
    // 変数名がgetter、setterとして外部と連携します。
    // 直接に値(フィールド)にアクセスするのではないので、これらは「フィールド」ではなく「プロパティ」と呼びます。
    // 要はJavaで言う所のメンバ変数をprivateで宣言してgetter, setterを用意した状態と同じで、メンバ変数名でgetter, setterが使用できるということです。
    val price: Int
    val speed: Int
    val name: String

    constructor(price: Int, speed: Int, name: String) {
        this.price = price
        this.speed = speed
        this.name = name
    }

    // 何も返さない時はvoidではなくUnit型
    fun displayInfo(): Unit {
        println("クラスのメソッド呼び出し↓")
        println("Name:" + this.name)
        println("MaxSpeed:" + this.speed)
        println("Price:" + this.price)
        return
    }

    // 複数の値を返せる関数
    fun addNumbers(a: Int, b: Int): Pair<Int, Int> {
        return Pair(a + 1, b + 1)
    }
}

// クラスのプライマリコンストラクタの書き方(Kotlinっぽい)
class Bike(name: String, maxSpeed: Int, price: Int) {
    val name = name
    val maxSpeed = maxSpeed
    val price = price
}

0 件のコメント:

コメントを投稿