반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 검색 기능 확장
- @Data
- @Setter
- K번째수
- 스프링 스케쥴러
- Java
- 영속 자료구조
- 정렬
- kubenetes
- 모던 자바 인 액션
- @configuration
- 스택/큐
- 다리를 지나는 트럭
- 코딩 테스트
- 완주하지 못한 선수
- 기능개발
- 쿠버네티스
- 전화번호 목록
- @Getter
- 프로그래머스
- 고차원 함수
- 롬복 어노테이션
- 루씬 인 액션
- 커링
- 해시
- H-index
- 가장 큰 수
- 알고리즘
- @EnableScheduling
- 크론 표현식
Archives
- Today
- Total
Today I Learned
코틀린에서 구현하는 유창성 (1) 본문
728x90
연산자 오버로딩
- 코틀린에서는 +, -, * 같은 연산자를 오버로딩해서 숫자 타입 뿐만 아니라 객체에도 사용할 수 있다.
operator fun Pair<Int, Int>.plus(other: Pair<Int, Int>) =
Pair(first + other.first, second + other.second)
- 연산자를 오버로딩하기 위해서 함수는 operator 키워드로 정의되어 있어야 한다.
- 연산자와 대응하는 메소드 이름은 아래 표와 같다.
연산자 | 대응하는 메소드 | 주의사항 |
+x | x.unaryPlus() | |
-x | x.unaryMinus() | |
!x | x.not() | |
x + y | x.plus(y) | |
x - y | x.minus(y) | |
x * y | x.times(y) | |
x / y | x.div(y) | |
x % y | x.rem(y) | |
++x | x.inc() | x는 할당 가능해야 함 |
x++ | x.inc() | x는 할당 가능해야 함 |
--x | x.dec() | x는 할당 가능해야 함 |
x-- | x.dec() | x는 할당 가능해야 함 |
x == y | x.equals(y) | |
x != y | !(x.equals(y)) | |
x < y | x.compareTo(y) | <=, >, >=도 사용 가능 |
x[i] | x.get(i) | |
x[i] = y | x.set(i , y) | |
y in x | x.contains(y) | !in으로도 사용 가능 |
x..y | x.rangeTo(y) | |
x() | x.invoke() | |
x(y) | x.invoke(y) |
확장 함수와 속성으 이용한 인젝팅
확장 함수를 이용한 메소드 인젝팅
data class Point(val x: Int, val y: Int)
data class Circle(val cx: Int, val cy: Int, val radius: Int)
- 점이 원 안에 있는지 찾는 기능을 구현하기 위해서 위의 두 클래스를 활용해보자.
fun Circle.contains(point: Point) =
(point.x - cx) * (point.x - cx) + (point.y - cy) * (point.y - cy) <
radius * radius
- contains() 확장 함수 안에서 암시적으로 Circle 클래스의 인스터스 멤버에 접근한다.
- 이 확장 함수가 클래스 내부의 인스턴스 메소드로 정의되었을 때와 동일하게 접근하는 것이다.
- 이 메소드를 Circle 클래스 내부에 작성할 경우 차이점은 fun Circle.contains(point: Point) 대신에 fun contains(point: Point)로 정의하는 것 뿐이다.
val circle = Circle(100, 100, 25)
val point1 = Point(110, 110)
val point2 = Point(10, 100)
- 확장 함수가 인스턴스 메소드와 같은 이름을 가지고 있어서 충돌이 발생하면, 항상 인스턴스 메소드가 실행된다.
- 인스턴스의 캡슐화된 부분에 접근할 수 있는 인스턴스 메소드와 다르게 확장 함수는 정의된 패키지 안에서 보이는 부분(public)에만 접근 가능하다.
확장 함수를 이용한 연산자 인젝팅
- 확장 함수는 연산자도 될 수 있다. contains() 메소드와 매핑되는 in 연산자를 사용해보자.
operator fun Circle.contains(point: Point) =
(point.x - cx) * (point.x - cx) + (point.y - cy) * (point.y - cy) <
radius * radius
println(circle.contains(point1)) //true
println(point1 in circle) //true
println(point2 in circle) //false
확장 속성을 이용한 속성 인젝팅
- 마찬가지로 확장 속성도 추가할 수 있다.
- 확장 속성은 클래스 내부에 존재하는 것이 아니기 때문에 백킹 필드를 가질 수 없다. 즉, field에 접근할 수 없다.
val Circle.area: Double
get() = kotlin.math.PI * radius * radius
val circle = Circle(100, 100, 25)
println("Area is ${circle.area}") //1963.49...
서드파티 클래스 인젝팅
fun String.isPalindrome(): Boolean {
return reversed() == this
}
- isPalindrome() 메소드는 코틀린의 확장 함수인 reversed()를 이용해서 현재 주어진 문자열이 palindrome인지 결정한다. 코드블록을 정의하는 대신, 이미 존재하는 메소드를 호출하는 단일 표현식을 사용할 수도 있다.
fun String.shout() = toUpperCase()
val str = "dad"
println(str.isPalindrome()) //true
println(str.shout()) //DAD
Static 메소드 인젝팅
- 클래스의 컴패니언 객체를 확장해서 static 메소드를 인젝팅할 수 있다.
fun String.Companion.toURL(link: String) = java.net.URL(link)
클래스 내부에서 인젝팅
- 확장 함수를 클래스 안에서 만든다면 해당 확장 함수는 해당 클래스와 해당 클래스의 이너 클래스에서만 볼 수 있다.
- 또한 확장 함수 안에는 2개의 리시버가 있다.
class Point(x: Int, y: Int) {
private val pair = Pair(x, y)
private val firstsign = if (pair.first < 0) "" else "+"
private val secondsign = if (pair.second < 0) "" else "+"
override fun toString() = pair.point2String()
fun Pair<Int, Int>.point2String() =
"(${firstsign}${first}, ${this@Point.secondsign}${this.second})"
}
println(Point(1, -3)) //(+1, -3)
println(Point(-3, 4)) //(-3, +4)
- Point 클래스에서 Pair<Int, Int>로 확장 함수를 인젝트했다. 그렇기 때문에 클래스 외부에서 Pair<Int, Int>의 확장 함수를 사용하려고 하면 컴파일 에러가 난다.
- 확장 함수가 클래스 내부에 생성되었기 때문에 확장 함수에는 this와 this@Point 두개의 리시버를 가지고 있다.
- 익스텐션 리시버는 확장 함수가 실행되는 객체이다.
- 디스패치 리시버는 확장 함수를 만들어 추가한 클래스의 인스턴스이다.
728x90
'Kotlin > 다재다능 코틀린 프로그래밍' 카테고리의 다른 글
코틀린에서 구현하는 유창성 (2) (1) | 2023.10.19 |
---|---|
내부 반복과 지연 연산 (0) | 2023.09.22 |
람다를 사용한 함수형 프로그래밍(2) (0) | 2023.09.22 |
함수형 코틀린 (1) (0) | 2023.09.08 |
델리게이션을 통한 확장 (2) (0) | 2023.09.08 |
Comments