코틀린 언어 정리 1-9

기본 - operator(연산자)

연산자 오버로딩

infix

함수 호출 시 중위 표기법을 지원하기 위한 키워드이며 단항 멤버 함수( 매개변수가 1개인 멤버 함수 및 확장함수 )선언 앞에 이 키워드를 추가하면 중위 표기법을 지원하는 함수로 처리됩니다.

 

중위 표기법( infix notation )이란

클래스의 멤버 함수( 확장 함수 포함 ) 호출 구문은 "객체이름.함수이름 ( 인수, ... )" 와 같은 문법을 가지는데 중위 표기법으로 표현하면 "객체이름 함수이름 인수"와 같이 표현할 수 있습니다. 즉 "."과 "()"를 생략할 수 있습니다.

 

예제

data class SimNum ( val value: Int ){}

infix fun SimNum.plus_sim ( oAddValue: SimNum ): SimNum {
   return SimNum ( value + oAddValue.value )
}

operator fun SimNum.plus ( oAddValue: SimNum ): SimNum {
   return SimNum ( value + oAddValue.value )
}

fun test () {
   var oNum1 = SimNum ( 10 )
   var oNum2 = SimNum ( 20 )

   var oNum3 = oNum1 plus_sim oNum2
   println("${oNum3.value}")

   //var oNum4 = oNum1 plus oNum2 // operator 함수를 명시적으로 호출할 때에는 중위표기법으로 호출할 수 없다.
   var oNum4 = oNum1.plus(oNum2)
   println("${oNum4.value}")

   var oNum5 = oNum1 + oNum2
   println("${oNum5.value}")
}

위의 예제를 보면 SimNum data class의 확장 함수로 plus_sim을 정의 했는데 이 함수의 정의 앞에 infix 키워드가 추가되어 있습니다. plus_sim을 호출한 부분은 test함수 내에서 확인할 수 있습니다.

 

효과

함수 호출 시 중위 표기법을 사용하면 함수가 연산자 처럼 보이는 효과가 있습니다.

 

주의

객체의 함수를 infix로 정의할 때 기존의 연산자( +, -, *, / 등 )와 대응하는 함수의 이름( ex. plus, minus, times, … 자세한 내용은 이후의 연산자들 항목 참조 )은 사용할 수 없습니다. 이 함수들을 재정의 할 때에는 operator 키워드를 사용해야 합니다.

 

operator

기존의 연산자( +, -, *, ... )를 재정의 할 때 사용하는 키워드입니다. 연산자와 대응하는 함수를 선언( ex. + 는 plus, - 는 minus, ... )할 때 함수 전체 선언 앞( fun 키워드 앞 )에 추가합니다.

 

예제

data class Dollars(val price: Int) {
   operator fun plus(dollarsToInc: Dollars): Dollars {
       return Dollars(price + dollarsToInc.price)
   }
}

fun test () {
   var price: Dollars = Dollars(10) + Dollars(20)
   println("Dollars: $price")
}

 

연산자들

다음은 각각의 연산자(+, -, *, /, ! 등의 기호)와 대응되는 문자 이름의 함수들입니다.( kotlinlang.org 참조 )

 

Unary operations

--------------------------

+a ⇒  a.unaryPlus()

-a ⇒  a.unaryMinus()

!a ⇒  a.not()

 

Increments and decrements

-----------------------------------------

a++ ⇒  a.inc()

a-- ⇒  a.dec()

 

Arithmetic operators

-------------------------------

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) (deprecated)

a..b ⇒  a.rangeTo(b)

 

'In' operator

------------------

a in b ⇒  b.contains(a)

a !in b ⇒  !b.contains(a)

 

Indexed access operator

------------------------------------

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)

 

Invoke operator

------------------------

a() ⇒  a.invoke()

a(i) ⇒  a.invoke(i)

a(i, j) ⇒  a.invoke(i, j)

a(i_1, ..., i_n) ⇒  a.invoke(i_1, ..., i_n)

 

Augmented assignments

-------------------------------------

a += b ⇒  a.plusAssign(b)

a -= b ⇒  a.minusAssign(b)

a *= b ⇒  a.timesAssign(b)

a /= b ⇒  a.divAssign(b)

a %= b ⇒  a.remAssign(b), a.modAssign(b) (deprecated)

 

Equality and inequality operators

------------------------------------------------

a == b ⇒  a?.equals(b) ?: (b === null)

a != b ⇒  !(a?.equals(b) ?: (b === null))

 

identity checks ( 재정의 불가능 )

--------------------------------------------

===, !==

 

Comparison operators

---------------------------------

a > b ⇒  a.compareTo(b) > 0

a < b ⇒  a.compareTo(b) < 0

a >= b ⇒  a.compareTo(b) >= 0

a <= b ⇒  a.compareTo(b) <= 0

 

Property delegation operators

--------------------------------------------

provideDelegate, getValue and setValue

 

class Delegate {

    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {

        return "$thisRef, thank you for delegating '${property.name}' to me!"

    }

 

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {

        println("$value has been assigned to '${property.name}' in $thisRef.")

    }

}

 

Infix calls for named functions

---------------------------------------------

연산자는 아니지만 연산자와 동일한 방법으로 사용할 수 있는 사용자 정의 함수를 구현할 수 있는 방법을 제공 합니다. 예를 들어, infix 키워드를 사용해 infixFunc 함수를 구현했다면 아래와 같은 두 가지 표현식을 모두 사용할 수 있습니다.

자세한 내용은 연산자 오버로딩의 infix 부분을 참고하시면 됩니다.

 

a infixFunc b ⇒  a.infixFunc(b)

 

요약

  • 코틀린에서 사용하는 +, -, / 등의 일반적인 연산자들은 모두 이와 대응하는 문자(영어) 이름의 함수가 존재하며 사용자가 재정의 하여 사용할 수 있습니다. ( ex. "+" 연산자의 경우 "plus" 함수를 오버로딩하여 재정의 가능 )
  • 기호로 정의된 거의 모든 연산자를 오버로딩할 수 있습니다.
  • infix notation(중위 표기법)으로 새로운 연산자(처럼 보이는 함수)도 만들 수 있습니다.

 

+ Recent posts