본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Effective Kotlin] Item 15 : Consider referencing receivers explicitly

by 돼지왕 왕돼지 2022. 3. 12.
반응형

이 글은 Effective Java 를 완독하고, Kotlin 을 상용으로 사용하는 개발자 입장에서
Effective Kotlin 글 중 새로운 내용, remind 할 필요 있는 부분, 핵심 내용 등만 추려 정리한 내용입니다.

 

#
extension receiver 란 "this" 같은 녀석을 말한다.

 

 

Many receivers

#
명시적인 receiver 를 사용하는 것은 scope 내에서 1개 이상의 receiver 가 있는 경우 유용하다.

class Node(val name:String){
	fun makeChild(childName: String) = create("$name.$childName").apply{ print("Created ${name}") }
	fun create(name : String): Node? = Node(name)
}

fun main() {
	val node = Node("parent")
	node.makeChild("child")
}

출력 결과는 "Created parent"
"Created parent.child" 를 하려면 print("Created ${this?.name}") 가 되어야 한다.

 

#
위 예제에서 apply 대신 also 를 사용하면 조금 더 에러 없이 "Created parent.child" 를 출력하도록 할 수 있다.

 

#
receiver 가 명확하지 않다면 우리는 그것을 피하던지 명시적 receiver 를 사용하도록 해야 한다.

 

 

DSL marker

#
Kotlin DSL 을 사용하는 경우 nested scope 와 함께 정말 많은 receiver 가 사용되곤 한다. 하지만 이 경우 우리는 explicit receiver 를 전혀 사용하지 않는다. Kotlin DSL 은 그렇게 디자인되었기 떄문이다.

DSL 에서 outer receiver 를 실수로 사용하는 것은 막기 위해서 @DslMarker 라는 annotation 이 도입되었다.

@DslMarker
annotation class HtmlDsl

fun table(f: TableDsl.() -> Unit){ /.../ }

@HtmlDsl
class TableDsl { /.../ }

table {
	tr {
		td { +"Column 1" }
		td { +"Column 2" }
		tr { // Compile error, this@table.tr 로 사용해면 가능하지만 사용하지 않는 것이 좋음.
			td { +"Value 1" }
			td { + "Value 2" }
		}
	}
}

 

 

Summary

 

 

 

반응형

댓글