2019年7月4日 星期四

Kotlin 的 data class 搭配有趣的運算子 operator fun

利用 data class 簡單就能定義複數(實部及虛部), 再定義出類型的運算方法:  operator fun plus( ), minus( ), times( ), div( ) 這四則運算, 就能用來計算複數, 若定義出 operator fun involke( ) 這個方法就能讓物件身兼特定功能(c++ 稱為 functor):
import kotlin.math.*
data class C(var r:Double, var i:Double) { // C: Complex number, r: real part, i:image part
        val square:Double =  r*r + i*i   // |C|2
        val length:Double = sqrt(square) // abs(C) = |C|  = sqrt(|C|2)
        operator fun plus(a:C):C { // +
            r += a.r
            i += a.i
            return this
        }
        operator fun minus(a:C):C {  // -
            r -= a.r
            i -= a.i
            return this
        }
        operator fun times(a:C):C { // *
            val temp = a.r * r - a.i * i // real part
            i = a.i*r + a.r*i  // image part
            r = temp
            return this
        }
        operator fun div(a:C):C { //  ÷
            if (a.length > 0f) {
                val temp = (a.r*r + a.i * i) / a.square // real part
                i = (a.i*r - a.r*i) / a.square  // image part
                r = temp
            } else throw Exception("Divide by zero(length=0)")
            return this
        }
        operator fun invoke( ):C{ // dump self complex number           
            val real = floor(r*100+0.5)/100 // 實部只顯示到小數點 2 位, 4 捨 5 入
            val imag = floor(i*100+0.5)/100 // 需部只顯示到小數點 2 位, 4 捨 5 入
            if (imag < 0) println("$real - ${-imag} i")  else  println("$real + $imag i")
            return this
        }
}   
fun main(){
    try {
         val c = ( ( C(3.0, 3.0) + C(2.0, 1.0) ) * C(9.0, 2.0) - C(10.0, 2.0) ) / C(5.0, 2.0)
          c( )  // Complex number dump: c = (((3 + 3i)+(2 + i))*(9 + 2i)-(10 + 2i))÷(5 + 2i)
    } catch (e:Exception){
        println(e.message)
    }
}
輸出結果:
7.68 - 5.72 i

沒有留言: