Kotlin In Action

Roeniss Moon·2022년 2월 18일
0

독서

목록 보기
11/29

생각나는 부분들

코틀린 컴파일 & 자바 컴파일 -> class 파일로 jar -> 코틀린 런타임에서 실행

if/when/throw is expression, not statement (try can be expression)

오버로딩 같은 상황에서 확장 함수가 클래스 내부 함수보다 우선순위가 낮다.

sealed class

by 키워드로 클래스 위임 (decorator 패턴 구현의 대안)

팩토리 패턴 by private constructor & companion object

sequence for lazy calculation in collection

플랫폼 타입: 코틀린이 null 관련 정보를 알 수 없는 (자바에서 가져온) 타입. 알아서 판단해야 함. (ex. String!)

원시/래퍼 타입 구분 X, 하지만 nullable 타입이라면 자바의 래퍼 타입으로 컴파일됨. (자바에선 원시 타입이 null일 수가 없어서)

Any 타입은 자바의 Object 에 해당함.

Array 클래스는 자바 배열(array)로 컴파일 됨

(여기부터 파트 2)

위임 프로퍼티

지연 로딩: by lazy 키워드를 쓸 수 있는데, 이는 정확히 말하자면 by 키워드와 위임 객체를 반환하는 표준 라이브러리 'lazy'의 결합이다.

일반 함수 호출의 경우엔 JVM이 필요할 경우 알아서 함수를 inline한다.

reified: inline 함수는 type erasure를 피할 수 있다. 이를 reify라고 한다. 이게 되는 이유: 컴파일러가 inline 함수 본문을 bytecode로 컴파일 해 호출되는 각 지점에 모두 삽입해버림. 따라서 구체적인 클래스(type)을 정확하게 알 수 있음.

모든 클래스가 무공변인 자바와 달리, 코틀린은 공변성을 띠는 경우가 있다.

  • 공변성: 타입 인자의 하위 타입 관계가 제네릭 타입에서도 유지된다.
  • out T: T는 공변적이다. 이 T는 리턴타입에 쓰일 수 있다, 즉 값을 produce한다. (Producer<out T>)
  • 생성자 파라미터는 in/out 어느쪽도 아니다.
  • var는 out/in, val은 out
  • private method는 적용받지 않는다. in/out의 영향을 받지 않는다 <- 변성 규칙은 외부의 사용자가 클래스를 잘못 사용하지 않게 하는 도구라서
  • 반공변성: 타입 인자의 하위 타입 관계가 제네릭 타입에서 뒤집힌다.
  • in T: T는 반공변적이다. 이 T는 파라미터 위치에서만 쓰인다. (Consumer<in T>)
  • 코틀린 표기의 (P) -> R은 사실 Function1<P, R> 이다.
  • (위처럼) 클래스 레벨에서 변성을 지정하면 선언 지점 변성, 메소드 레벨에서 지정하면 사용 지점 변성이다. 후자처럼 하면 모든 지점에 명시해야 된다. (ex. ? extends X, ? super Y)

리플렉션: "실행 시점에 코틀린 객체의 내부를 관찰하기"

DSL: 구조화된 API 구축에 유리

  • 확장 함수 타입과 수신 객체 지정 람다 이용하기
fun buildStr(action: StringBuilder.() -> Unit): String {
    val sb = StringBuilder()
    sb += "asd"
    sb.action()
    sb.toString()
}

buildStr { this.append("!") } // "asd!"
  • @DslMaker로 여러 단계 바깥의 this에 접근 못하게 통제 가능
  • 많이 보이는 패턴: fun table(init: TABLE.() -> Unit) = TABLE().apply(init)
  • invoke를 이용해 조금 더 다양한(?) 사용방법 제공:
class DependencyHandler { 
    fun compile(coordinate: String){
        TODO()
    }
    
    operator fun invoke(body: DependencyHandler.() -> Unit){
        body()
    }
}

// compile 사용
dependencies.compile("junit")

// invoke (and compile) 사용
dependencies {
    compile("junit")
}

suspend: CPS (continuation passing style) 변환과 state machine을 활용해 코드를 생성해내고, 이를 통해 함수에 들어가고 나가는 부분을 여러 순간으로 나눌 수 있다. (코루틴은 추가로 알아볼 예정)

감상

좋은 책 같긴 한데, 뭔가 읽은 분량에 비해 새로 배운건 많지 않은 것 같다. 조금 더 어려운 책을 찾는게 나을 것 같다.

profile
기능이 아니라 버그예요

0개의 댓글