11장에서 다루는 내용
- 영역 특화 언어 만들기
- 수신 객체 지정 람다 사용
- invoke 관례 사용
- 기존 코틀린 DSL 예제
확장함수를 사용해서 함수를 자연어처럼 쓰는건 멋지긴 한데... 잘 안쓸것 같다. 근데 이것이 진짜 코틀린처럼 쓰는거라며 언어 제작자가 미는 느낌.
나중에 쓰게 된다면 그때 자세히 보는걸로
11.1 API에서 DSL로
일반 구문 | 간결한 구문 | 사용한 언어 특성 |
StringUtil.capitalize(s) | s.capitalize() | 확장 함수 |
1.to("one") | 1 to one | 중위 호출 |
set.add(2) | set += 2 | 연사자 오버로딩 |
map.get("key") | map["key"] | get 메서드에 대한 관례 |
file.use({ f -> f.read() }) | file.use { it.read() } | 람다를 괄호 밖으로 빼내는 관례 |
sb.append("yes") sb.append("no") |
with (ab) { append("yes") append("no") } |
수신 객체 지정 람다 |
SDL(Domain-Specific Language, 영역 특화 언어)은 평소에 아는 java같은 범용 프로그래밍 언어(general-purpose programming language)와는 다르게 하나의 역할만 하기 위해 존재한다. SQL 같은거. 그래서 그거에 특화되있음. 하지만 그렇기에 거기에 대한 안의 작동 방식은 몰라도 된다. 코틀린도 비슷하게 만들 수 있으며, 장점은 코틀린에서 구현하는 것이므로 일반 다른 변수 같은것들도 쉽게 넣을 수 있다. 외부 DSL로는 SQL을 사용하며, 내부 DSL로는 코틀린으로 작성된 데이터베이스 프레임워크인 익스포즈드(Exposed) 프레임워크가 제공하는 DSL을 사용한다.
SELECT Country.name, COUNT(Customer.id)
FROM Country
JOIN Customer
ON Country.id = Customer.country_id
GROUP BY Country.name
ORDER BY COUNT(Customer.id) DESC
LIMIT 1;
(Country join Customer)
.select(Country.name, count(Customer.id))
.selectAll()
.groupBy(Country.name)
.orderBy(count(Customer.id), Order.DESC)
kotlinx.html 라이브러리를 사용해서 html를 작성한 내용이다.
fun createAnotherTable() = createHTML().table {
val numbers = mapOf(1 to "one", 2 to "two")
for ((num, string) in numbers) {
tr {
td { +num.toString() }
td { +string }
}
}
}
kotlin언어기 때문에 내부에 변수 작성 가능.
11.2 구조화된 API 구축: DSL에서 수신 객체 지정 DSL 사용
확장 함수 타입이라는 타입이라는게 있다. 놀랍게도 말장난이 아니다.
다음은 람다를 인자도 받는 buildString() 정의를 일반적으로 한 것과 수신 객체 지정 람다로 한 방법이다.
fun buildString(
buildAction: (StringBuilder) -> Unit
): String {
val sb = StringBuilder()
buildAction(sb)
return sb.toString()
}
val s = buildString {
it.append("Hello, ")
it.append("World!")
}
print(s) // Hello, World!
fun buildString(
buildAction: StringBuilder.() -> Unit
): String {
val sb = StringBuilder()
buildAction(sb)
return sb.toString()
}
val s = buildString {
this.append("Hello, ")
append("World!")
}
print(s) // Hello, World!


val appendExcl : StringBuilder.() -> Unit =
{ this.append("!") }
val stringBuilder = StringBuilder("Hi")
stringBuilder.appendExcl()
println(stringBuilder) // Hi!
println(buildString(appendExcl)) // !
'CS > 코틀린 인 액션' 카테고리의 다른 글
부록 E. 코루틴과 Async/Await (0) | 2023.05.17 |
---|---|
10. 애노테이션과 리플렉션 (0) | 2023.05.10 |
9. 제네릭스 (0) | 2023.05.05 |
8. 고차 함수: 파라미터와 반환 값으로 람다 사용 (0) | 2023.05.05 |
7. 연산자 오버로딩과 기타 관례 (0) | 2023.05.03 |