KotlinDive

プログラミング言語 Kotlin についての入門ブログです。

基本的な演算

1. 演算子

Kotlinでは一般的な演算がサポートされています。
それぞれの演算子には対応する予め決められたメンバ関数かエクステンション関数があります。
operator修飾子をつけて、これらの関数をオーバーロードすることができます。

2. 単項演算子

他のプログラミング言語でも一般的に利用できる演算子がサポートされています。

対応する関数
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.inc()
a-- a.dec()
++a a.inc()
--a a.dec()

3. 二項演算

3-1. 算術演算子

算術演算を行う二項演算子も、単項演算子と同じように一般的なものがサポートされています。

対応する関数
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.rem(b), a.mod(b)
   

3-2. レンジ演算子とイン演算子

Kotlinには、範囲を表すためのRange演算子と範囲内にあるかどうかを判定するIn演算子があります。
これらを利用することで、条件式などをスマートに記述することができます。

対応する関数
a..b a.rangeTo(b)
a in b b.contains(a)
a !in b !b.contains(a)

fun main(args: Array) {
    check(5)
}

fun check(x: Int) {
    if (x in 0..9) {
        println("a is in 0 to 9.")
    }
    else {
        println("a is not in 0 to 9.")
    }
}

a is in 0 to 9.

3-3. インデックスアクセス演算子

インデックスアクセス演算子はいわゆる[i]で配列やコレクションの要素にアクセスするための演算子です。
Kotlinでは要素の一部に対するアクセスのサポートされています。

対応する関数
a[i] a.get(i)
a[i, j] a.get(i, j)
a[i_1, ... , i_n] a.get(i_1, ... , i_n)
a[i] = b a.set(i, b)
a[i, j] = b a.set(i, j, b)
a[i_1, ... , i_n] = b a.set(i_1, ... , i_n, b)

3-4. 代入演算子

対応する関数
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.remAssign8b), a.modAssign(b)

3-5. 比較演算子

対応する関数
a == b a?.equals(b) ?: (b === null)
a != b !(a?.equals(b) ?: (b === null)
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
a >= b a.compareTo(b) >= 0
a <= b a.compareTo(b) <= 0

4. operator演算子

この章の冒頭でもご紹介したように、oprator演算子をつけて対応する関数を作成することで、 自作クラスでも演算子が使えるようになります.


fun main(args: Array) {
    val a = Point3D(10.0, 20.0, 30.0)
    val b = Point3D(1.0, 2.0, 3.0)

    println(a)
    println(-a)
    println(a - b)
    println("x: ${a[0]}, y: ${a[1]}, z: ${a[2]}")

    a[0] = 100.0
    a[1] = 200.0
    a[2] = 300.0
    println(a)
}

data class Point3D(var x: Double, var y: Double, var z: Double) {
    operator fun unaryMinus() = Point3D(-x, -y, -z)
    operator fun minus(b: Point3D) = Point3D(x - b.x, y - b.y, z - b.z)
    operator fun get(i: Int): Double? = when (i) {
        0 -> x
        1 -> y
        2 -> z
        else -> null
    }
    operator fun set(i: Int, value: Double) = when (i) {
        0 -> {
            x = value
        }
        1 -> {
            y = value
        }
        2 -> {
            z = value
        }
        else -> {
            print("out of range.")
        }
    }
}

Point3D(x=10.0, y=20.0, z=30.0)
Point3D(x=-10.0, y=-20.0, z=-30.0)
Point3D(x=9.0, y=18.0, z=27.0)
x: 10.0, y: 20.0, z: 30.0
Point3D(x=100.0, y=200.0, z=300.0)

5. ビット演算

ビット演算には+や/=のような特別な記号ははく、中置記法も利用できる関数としてサポートされています。

関数 内容
shl(bits) 符号付き左シフト(Javaでいう <<)
shr(bits) 符号付き右シフト(Javaでいう >>)
ushr(bits) 符号なし右シフト(Javaでいう >>>)
and(bits) ビット論理積
or(bits) ビット論理和
xor(bits) ビット排他的論理和
inv(bits) ビット反転

fun main(args: Array) {
    val a = 1
    println(a)

    // 通常の関数のように利用することも可能
    println(a.shl(1))
    println(a.shl(2))

    // 中置記法で記述も可能
    println(a shl 3)
    println(a shl 4)
}