개발/Kotlin

연산자 오버로딩과 기타 관례(convention) (2/3)

귀찮은게 많은 개발자 2022. 1. 5. 15:40
728x90

https://eddie-rody.tistory.com/16

 

연산자 오버로딩과 기타 관례(convention) (1/3)

이항 산술 연산 오버로딩 오버로딩 가능한 이항 산술 연산자 식 함수 이름 a * b times a / b div a % b mod (1.1 부터 rem) a + b plus a - b minus // plus 연산자 구현하기 data class Point(val x: Int, val y..

eddie-rody.tistory.com

이 글에 이어 정리합니다.


  • get, set
    • 변경 가능 맵에 키/값 쌍을 넣거나 이미 맵에 들어있는 키/값 연관 관계를 변경할 수 있다.
// get 구현하기
operator fun Point.get(index: Int): Int {
	return when(index) {
		0 -> x
		1 -> y
		else ->
			throw IndexOutOfBoundsException("Invalid coordinate $index")
	}
}

>>> val p = Point(10, 20)
>>> println(p[1])
20


// 각괄호는 get 함수 호출로 변환된다.
x[a, b] --> x.get(a, b)


// set 구현하기
data class MutablePoint(var x: Int, var y: Int)

operator fun MutablePoint(index: Int, value: Int) {
	when(index) {
		0 -> x = value
		1 -> y = value
		else ->
			throw IndexOutOfBoundsException("Invalid coordinate $index")
	}
}

>>> val p = MutablePoint(10, 20)
>>> p[1] = 42
>>> println(p)
MutablePoint(x=10, y=42)


// 각괄호는 set 함수 호출로 변환된다.
x[a, b] = c --> x.set(a, b, c)

 

  • in
    • in은 객체가 컬렉션에 들어 있는지 검사한다.
data class Rectangle(val upperLeft: Point, val lowerRight: Point)

operator fun Rectangle.contains(p: Point): Boolean {
	return p.x in upperLeft.x until lowerRight.x && p.y in upperLeft.y until lowerRight.y
}

>>> val rect = Rectangle(Point(10, 20), Point(50, 50))
>>> println(Point(20, 30) in rect)
true
>>> println(Point(5, 5) in rect)
false


// in 연산자는 contains 함수로 변환된다.
a in c --> c.contains(a)

 

  • rangeTo
    • 범위를 만들려면 .. 구문을 사용해야 한다.
    • start..end --> start.rangeTo(end) 로 컴파일된다.
    • Comparable 인터페이스를 구현하면 rangeTo를 정의할 필요가 없다.
// 날짜의 범위
>>> val now = LocalDate.now()
>>> val vacation = now..now.plusDays(10)
>>> println(now.plusWeeks(1) in vacation)
true


// 날짜 범위에 대한 이터레이터 구현
operator fun ClosedRange<LocalDate>.iterator(): Iterator<LocalDate> =
	object : Iterator<LocalDate> {
		var current = start
		override fun hasNext() = current <= endInclusive
		override fun next() = current.apply {
			current = plusDays(1)
		}
	}

>>> val newYear = LocalDate.ofYearDay(2017, 1)
>>> val daysOff = newYear.minusDays(1)..newYear
>>> for (dayOff in daysOff) { println(dayOff) }
2016-12-31
2017-01-01

 

  • 구조 분해 선언
    • 복합적인 값을 분해해서 여러 다른 변수를 한꺼번에 초기화할 수 있다.
    • 함수에서 여러 값을 반환할 때 유용하다.
// 파일명과 확장자로 나누기
data class NameComponents(val name: String, val extension: String)

fun splitFilename(fullName: String): NameComponents {
	val result = fullName.split('.', limit = 2)
	return NameComponents(result[0], result[1])
}

>>> val (name, ext) = splitFilename("example.kt")
>>> println(name)
example
>>> println(ext)
kt


// 구조 분해를 이용한 맵 이터레이션
fun printEntries(map: Map<String, String>) {
	for ((key, value) in map) {
		println("$key -> $value")
	}
}

>>> val map = mapOf("Oracle" to "Java", "JetBrains" to "Kotlin")
>>> printEntries(map)
Oracle -> Java
JetBrains -> Kotlin

 


나머지 내용은 아래의 링크로 확인해주세요.

https://eddie-rody.tistory.com/18

 

연산자 오버로딩과 기타 관례(convention) (3/3)

https://eddie-rody.tistory.com/16 연산자 오버로딩과 기타 관례(convention) (1/3) 이항 산술 연산 오버로딩 오버로딩 가능한 이항 산술 연산자 식 함수 이름 a * b times a / b div a % b mod (1.1 부터 rem) a..

eddie-rody.tistory.com

 

728x90