Skip to content

Latest commit

 

History

History
178 lines (106 loc) · 5.86 KB

2회차.md

File metadata and controls

178 lines (106 loc) · 5.86 KB

KClass

KClass 라는 리플랙션 데이터를 얻는 방법

  • 클래스::class
  • 인스턴스::class

코틀린 리플랙션 객체는 자바 리플랙션 객체와는 다르다.

코틀린 내부에서 컴파일 과정에서 도출된 메타 데이터를 가지고 있음


KClass.members - 속성, 메소드 일체

  • Collection<KCallable<*>> 로 표현된다.

코틀린 컬랙션

image

-List, Set, Map 모두 Collection 을 가르킨다.


KCallable - 호출 가능한 모든 요소

  • KProperty: 속성
  • KFunction: 함수, 메서드

코틀린은 클래스의 속성을 만들면 값이 아니라 getter/setter 를 만드는 메소드로 인식 ?? 속성을 만드는 것 자체가 getter/setter 를 만드는 것과 같다.

image

  • 필터는 걸러낼 뿐이지 여전히 it 은 KCallable 이다.

프로그래밍 언어의 문과 식

  • "문(Statement)" 은 컴파일 되고 난뒤, CPU 에 내리는 명령으로 바뀜
  • "식(Expression)" 은 컴파일 되고 난뒤, 메모리에 올라가는 값으로 바뀜. -> 식은 값으로 규결된다.

함수형 언어는 Statement 를 Expression 으로 바꾸는 케이스가 많다.

예를들어 루비는 statemenet 가 없다.

Statement 는 한번 실행하면 끝나고, 여러번 실행시킬수 없고 제어하기 힘들다. 그리고 Runtime 에 유언성을 확보하기 위해 Expression 으로 많이 바꿈.


Smart casting

image

코틀린은 문을 해석하는 순서가 위에서 아래로 향한다.

위에서 타입을 확정지으면, 아래 코드는 그것을 받아들인다.

즉 위 코드처럼 위에서 null 을 체크했기 때문에 아래 코드에서는 null 을 체크하지 않는다.


Matcher

Java 나 C 의 Switch, case 문은 바이트코드로 해석이 되거나 어셈블리가 작동할때 router map 처럼 작동하기 때문에

동시에 그 값이 어디로 들어갈지 분기처리를 한디.

하지만 코틀린은 위에서 아래로 순차적으로 해석한다. 그래서 스마트캐스팅이 가능하다.

단점으로는 케이스가 너무 많다면 코틀린은 부하가 생길 수 밖에 없다. 반면에 Java 나 C 는 부하가 증가하지 않는다.

그렇기 때문에 많이 걸리는 케이스들을 위로 올리는 것이 유리하다.


중복 ? (사실 잘 이해 못함)

코드의 중복이라는 것은 존재하는 것이 아니라 발견되는 것이다 - 구현패턴, 캔트백

AS-IS

fun <T : Any> jsonObject(target: T): String {
    val builder = buildString {
        target::class.members
            .filterIsInstance<KProperty<*>>()
            .joinTo(buffer = this, separator = ", ", prefix = "{", postfix = "}") {
                val value = it.getter.call(target)
                "${jsonString(it.name)} : ${when (value) {
                    null -> "null"
                    is String -> jsonString(value)
                    is Boolean, is Number -> value.toString()
                    is List<*> -> jsonList(value)
                    else -> jsonObject(value)
                }}"
            }
    }

    return builder
}

TO-BE

fun <T : Any> jsonObject(target: T): String {
    val builder = buildString {
        target::class.members
            .filterIsInstance<KProperty<*>>()
            .joinTo(buffer = this, separator = ", ", prefix = "{", postfix = "}") {
                "${jsonValue(it.name)} : ${jsonValue(it.getter.call(target))}"
            }
    }

    return builder
}

KFunction

함수의 레퍼러스를 얻는 방법: :: 함수, 인스턴스::메소드

리플랙션으로 함수의 레퍼런스를 얻는 다는 것은 기존의 레퍼런스를 얻는 것이 아닌 메소드를 호출하는 새로운 람다를 생성하는 것이다. (자바로 마찬가지)


Named Argument

image


확장함수

image

Extension Function 에 접근제한자를 private 으로 걸면 그 function 은 해당 파일내에서만 사용 가능하다.

프로그래밍은 세부적으로 작성할 수록 범용성이 떨어진다.

확장 함수로 마음껏 오버로딩이 가능하다

image

모든 객체라면 위 4개 확장함수를 사용할 수 있다.

코드를 트랜잭션 블록을 선언하는 것과 같다 ?? <- 건들 수 없는 블록

apply

메소드 체이닝이 안되는 객체도 apply 를 통해 메소드 체이닝이 가능해진다. 왜냐하면 확장함수 형태로 들어오기 때문에 ??

코틀린에서는 return this 를 하지 않고 apply 를 사용해도된다.

also

확장함수 형태가 아닌 인자로 넘어온다.

run, let 은 반환하는 인자가 다르다.


Annotation

image

코드 외적으로 힌트를 추가하는 메타프로그래밍이라고 볼 수 있다.

Annotation 의 장점은 기존 로직에 아무런 영향도 없다.

자바는 바이너리로 애노테이션을 저장하기 때문에 런타임에 사용할 수 없다. 그래서 특수한 ?? 기능을 사용하여 다룰 수 있음

코틀린은 기본 값이 런타임이라 실행 중에 언제든지 값을 얻어낼 수 있다.

애노테이션의 단점 -> 코드 힌트가 되지 않아 존재 조차 모를 수 있음