2023 02 04 코틀린 공부 DSL
DSL (Domain Specific Language) : 영역 특화 언어 - 가장 익숙한 DSL은 SQL과 정규식 등이다. 보통의 범용 프로그래밍 언어와 달리 선언적이며 원하는 결과를 기술하기만 하고 과정은 언어를 해석하는 엔진이 한다.
장점으로는 전체 과정을 한꺼번에 최적화하기 때문에 범용 프로그래밍언어와 달리 더 효율적일 수 있다.
단점은 DSL을 범용 언어로 만든 호스트 애플리케이션과 조합하기 어렵다. DSL의 자체 문법이 있어 다른 언어의 프로그램 안에 직접 포함시킬 수 없고 별도의 파일이나 문자열로 저장해야 한다. 또한 컴파일 시점에서 제대로 검증하거나 디버깅하거나 IDE를 제공하기 어려워진다.
독립적인 문법을 가진 외부DSL과 달리 내부DSL은 범용 프로그램의 일부로 동일한 문법을 사용한다. 코틀린에서 html을 다룰 수 있는것 또한 내부DSL을 이용하여 다룰 수 있다.
한 호출 시퀀스에 아무런 구조 없이 한번에 하나씩 호출하는 일반 API와의 차이점은 람다를 중첩하거나 메서드 호출을 연쇄시키는 방식으로 구조를 만든다
일반 람다 함수의 람다를 수신 객체 지정 람다로 변경하면 더 간단하게 호출할 수 있다.
아래의 경우는 일반 람다이며 it.append()로 호출해야한다.
fun buildString(
builderAction: (StringBuilder) -> Unit
): String {
val sb = StringBuilder()
builderAction(sb)
return sb.toString()
}
val s = buildString { it.append("Hello")
it.append("World")}
수신 객체 지정 람다로 바꾸면 아래의 코드처럼 it 없이 쓸 수 있다. (StringBuilder) -> Unit 을 Stringbuilder.() -> Unit 으로 바꿨다. 수신객체 sb가 this가 된다.
fun buildString(
builderAction: StringBuilder.() -> Unit
): String {
val sb = StringBuilder()
sb.builderAction()
return sb.toString()
}
val s = buildString { this.append("Hello")
append("World")}
.을 기준으로 앞은 수신 객체 타입 괄호안은 파라미터 타입, 리턴되는곳이 반환타입이다.
apply, with는 모두 제공받은 수신 객체로 확장 함수 타입의 람다를 호출한다. apply는 수신 객체를 this로 반고 with는 수신 객체의 첫 파라미터로 받는다. apply는 수신 객체를, with는 결과를 반환한다.