TIL

아이템 46 함수 타입 파라미터를 갖는 함수에 inline 한정자를 붙여라

inline fun repeat(times: Int, action: (Int) -> Unit) {
	for (index in 0 until times) { action(index) }
}
repeat(10) { print(it) }

// 컴파일 후
for (index in 0 until times) { 
	print(index) 
}

타입 아규먼트를 reified로 사용할 수 있다.

fun <T> printTypeName() {
	print(T::class.simpleName) // 오류
}
inline fun <reified T> printTypeName() {
	print(T::class.simpleName)
}

// 사용
printTypeName<Int>() // Int
printTypeName<Char>() // Char
printTypeName<String>() // String

함수 타입 파라미터를 가진 함수가 훨씬 빠르게 동작

var l = 1L
noinlineRepeat(100_000_000) {
	l += it
}

// 인라인이 아닌 람다에선 지역 변수 l을 직접 사용할 수 없어
// 컴파일 중 아래와 같이 레퍼런스 객체로 래핑되고
// 람다 표현식 내부에선 이를 사용한다.
val a = Ref.LongRef()
a.element = 1L
noinlineRepeat(100_000_000) {
	a.element = a.element + it
}

비지역적 리턴(non-local return)을 사용할 수 있다.

fun main() {
	repeatNoinline(10) {
		print(it)
		return // 오류
	}
}
fun main() {
	repeat(10) {
		print(it)
		return // OK
	}
}

inline 한정자의 비용

inline fun a() { b() }
inline fun b() { c() }
inline fun c() { a() }
internal inline fun read() {
	var reader = Reader() // 오류
	// ...
}

private class Reader {
	// ...
}
inline fun requestNewToken(
	hasToken: Boolean,
	crossinline onRefresh: () -> Unit,
	noinline onGenerate: () -> Unit,
) { /* ... */ }