분류 전체보기 154

[Kotlin] 런타임 시 제네릭의 동작: 타입 소거(Type erasure), reified 타입 파라미터

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 런타임의 제네릭: 타입 소거(type erasure) 자바와 마찬가지로 코틀린 제네릭 타입 인자 정보는 런타임에 지워진다. 제네릭 인스턴스가 생성될 때 쓰인 타입 인자에 대한 정보를 유지하지 않는다. 예를 들어 `List` 객체를 만들더라도, 런타임에는 그 객체를 오직 `List` 로만 볼 수 있다. 즉, 그 `List` 객체가 어떤 타입의 원소를 저장하는지 런타임에는 알 수 없다. 이를 타입 소거 (type erasure) 라고 한다. 런타임에 둘은 완전히 같은 타입의 객체이다. 하지만 컴파일러가 타입 인자를 알고 올바른 타입의 값만 각 리스트에 넣도록 보장해주기 때문에 `List` 에..

Kotlin 2024.01.31

[Kotlin] 제네릭 타입 파라미터(Generic Type Parameter)

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 제네릭 타입 파라미터 제네릭스를 사용하면 타입 파라미터(type parameter)를 받는 타입을 정의할 수 있다. 제네릭 타입의 인스턴스를 만드려면 타입 파라미터를 구체적인 타입 인자(type argument)로 치환해야 한다. 예를 들어 코틀린의 `List` 는 `List` 로 되어 있다. 이에 대한 인스턴스를 만들 때는 `List` 의 모습으로 구체적인 타입 인자를 지정하여 사용한다. 타입 파라미터는 여러 개가 될 수도 있다. 예를 들어 코틀린의 `Map` 은 `Map` 이다. 이런 제네릭 클래스는 `Map` 처럼 구체적인 타입 인자를 지정하여 인스턴스화한다. 코틀린 컴파일러는 보통 ..

Kotlin 2024.01.31

[Kotlin] 고차 함수 안에서 흐름 제어

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. filter 와 함께 람다 안에서 return 을 사용하는 등의 예제를 살펴보자. 람다 안의 return 문: 람다를 둘러싼 함수로부터 리턴(non-local return) 일반 루프 안에서 `return` 사용하기 data class Person(val name: String, val age: Int) fun lookForAlice(people: List) { for (person in people) { if (person.name == "Alice") { println("Found!") return } } println("Alice is not found") } val people = ..

Kotlin 2024.01.30

[Kotlin] 인라인(inline) 함수

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 인라인 함수를 사용하여 람다를 사용함에 따라 발생할 수 있는 성능상 부가 비용을 없앨 수 있다. 아래는 이전 글(자바 함수형(SAM) 인터페이스 활용)에서 설명한 것들이다. 코틀린은 보통 람다를 익명 클래스로 컴파일하지만, 람다 식을 사용할 때마다 새로운 클래스가 만들어지지는 않는다. 또한 람다가 변수를 캡처(포획)하면 람다가 생성되는 시점마다 새로운 익명 클래스 객체가 생긴다. 이런 경우 런타임에 익명 클래스 생성에 따른 부가 비용이 든다. 따라서 람다를 사용하는 구현은 똑같은 작업을 수행하는 일반 함수를 사용한 구현보다 덜 효율적이다. 하지만 `inline` 변경자를 어떤 함수에 붙이면..

Kotlin 2024.01.26

[Kotlin] 고차함수

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 고차함수(high order function): 람다를 인자로 받거나 리턴하는 함수 고차함수로 코드를 더 간단히 하고, 중복을 없애고 더 나은 추상화 구축 가능 함수형 프로그래밍 먼저 함수형 프로그래밍의 정의를 찾아보자. 함수형 프로그래밍(functional programming): 자료 처리를 수학적 함수의 계산으로 취급하고, 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임 중 하나이다. - 위키백과 부수 효과가 없는 순수 함수를 1급 객체(시민)로 간주하여 패러미터로 넘기거나 리턴값으로 사용할 수 있다. 또 참조 투명성을 지킬 수 있다. 1급 객체는 아래 특징을 가진다. 일급 객체는 ..

Kotlin 2024.01.26

[Kotlin] 프로퍼티 접근자 로직 재활용: 위임 프로퍼티

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 위임 프로퍼티(delegated property)는 코틀린이 제공하는 convention(관례)에 의존하는 독특하면서 강력한 기능이다. 이를 사용하면 값을 backing property 에 단순히 저장하는 것보다 더 복잡한 방식으로 작동하는 프로퍼티를 쉽게 구현할 수 있다. 또 그 과정에서 접근자(getter/setter)로직을 매번 재구현할 필요도 없다. 예를 들어 자신의 값을 필드가 아닌, DB TABLE 이나 브라우저 세션, 맵 등에 저장할 수 있다. 위임은 객체가 직접 작업을 수행하지 않고 다른 도우미 객체가 그 작업을 처리하게 맡기는 디자인 패턴이다. 이 때 도우미 객체를 위임 객..

Kotlin 2024.01.25

[Kotlin] 구조 분해 선언과 component 함수

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 이전에 data class 를 다룬 글에서 간단히 구조 분해 선언(destructuring declaration) 을 살펴보았다 구조 분해를 사용하면 복합적인 값을 분해해서 여러 다른 변수를 한꺼번에 초기화할 수 있다. 구조 분해를 사용하는 방법 val p = Point(10, 20) val (x, y) = p assert(x == 10 && y == 20) 구조 분해 선언은 일반 변수 선언과 비슷하지만 `=` 의 좌변에 여러 변수를 괄호로 묶는다. 구조 분해 선언은 내부적으로 관례를 사용 내부에서 구조 분해 선언은 관례를 사용한다. 구조 분해 선언의 각 변수를 초기화하기 위해 `compo..

Kotlin 2024.01.24

[Kotlin] 컬렉션과 범위에 대해 쓸 수 있는 convention(관례)

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 컬렉션에는 인덱스 연산자(`a[b]`) 를 사용항 인덱스로 원소를 설정하거나 가져올 수 있다. `in` 연산자는 원소가 컬렉션이나 범위에 속하는지 검사하거나 원소를 iteration 할 때 사용한다. 커스텀 클래스에서 이러한 연산들을 추가할 수 있다. 인덱스로 원소에 접근: get & set 코틀린이나 자바에서 맵이나 배열 원소에 접근할 때 모두 `[]` 을 사용한다. 코틀린에서는 인덱스 연산자도 convention 을 따른다. 인덱스 연산자를 사용해 원소를 읽는 연산 -> `get` 연산자 메서드로 변환 인덱스 연산자를 사용해 원소를 쓰는 연산 -> `set` 연산자 메서드로 변환 `Po..

Kotlin 2024.01.24

[Kotlin] 비교 연산자 오버로딩

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 코틀린에서는 산술 연산자와 마찬가지로 원시 타입 값뿐 아니라 모든 객체에 대해 비교 연산을 수행할 수 있다. 자바에서는 객체 비교 시 `equals` 나 `compareTo` 를 호출해야 함 코틀린에서는 `==` 비교 연산자를 오버로딩하여 사용 가능 이번에는 비교 연산자를 지원하는 convention(관례) 를 살펴보자. 동등성 연산자: equals 코틀린은 `==` 연산자 호출을 `equals` 메서드 호출로 컴파일한다. 이는 다른 산술 연산자 오버로딩처럼 convention 을 적용한 것이다. `!=` 연산자를 사용하는 식도 `equals` 호출로 컴파일된다. (비교 결과를 뒤집은 값을..

Kotlin 2024.01.24

[Kotlin] 산술 연산자 오버로딩

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 코틀린에서는 어떤 언어 기능과 미리 정해진 이름의 함수를 연결해주는 기법을 convention(관례)라고 한다. 언어 기능을 타입에 의존하는 자바와 달리 코틀린은 함수 이름을 통한 convention 에 의존한다. 자바에서는 원시 타입, `String` 에 대해서만 산술 연산자를 사용할 수 있다. 코틀린에서는 다른 클래스에서도 산술 연산자를 사용할 수 있다. 이항 산술 연산 오버로딩 `plus` 연산자 구현하기 data class Point(val x: Int, val y: Int) { operator fun plus(other: Point): Point { // plus 라는 이름의 연산..

Kotlin 2024.01.23