KOTLIN 23

[KOTLIN] 불필요한 객체 생성을 피하라

객체 생성 비용 발생하는 경우 64비트 JDK에서 객체는 8바이트의 배수, +_앞부분은 12바이트 헤더 캡슐화된 객체는 함수 호출 비용이 발생하며 비용은 크지는 않지만 티끌모아태산임 객체 생성시 비용이 발생함 불필요한 객체를 제거할 방법 객체 선언 객체를 재사용함 캐시를 활용하는 팩토리 함수 팩토리 메서드를 가지면 캐시를 가질수 있음 쓰레드풀, 커넥션풀 등 객체생성이 무겁고 동시에 여러 mutable 객체를 사용하는 경우 적합함 모든순수 함수는 캐싱을 활용할 수 있음 (메모이제이션)적합 캐싱처리하면 대신 메모리 사용은 증가, 적절하게 활용해야함 private val FIB_CACHE = mutableMapOf() //캐싱 처리해서 재사용 예시 fun fib(n: Int): BigInteger = FIB_..

KOTLIN 2022.08.03

[KOTLIN] SEALED CLASS

Sealed 클래스 자기 자신이 추상클래스이고, 자신을 상속받는 여러 서브 클래스들을 가질 수 있음 enum 클래스와 달리 상속을 지원하여, 상속을 활용하여 구현이 가능 자신을 상속받는 서브 클래스의 종류를 제한할 수 있음 Sealed 클래스 특징 서브 클래스들은 반드시 같은 파일 내에 선언 되어야함 sealed 클래스는 기본적으로 추상클래스임 sealed 클래스는 private 생성자를 기본적으로 가지게 됨 Sealed 클래스 예시 sealed class Color { data class Red(val r: Int, val g: Int, val b: Int) : Color() data class Orange(val r: Int, val g: Int, val b: Int) : Color() data cl..

KOTLIN 2022.07.27

[KOTLIN] 멤버 확장 함수의 사용을 피하라 (이펙티브 코틀린)

멤버 확장 함수의 사용을 피하라 어떤 클래스에 대한 확장함수를 정의할 때 이를 멤버로 추가하는 것은 좋지 않음 암묵적 접근을 할 때 두 리시버 중에서 어떤 리시버가 선택될지 혼란스러움 class A { val a = 10 } class B { val a = 20 val b = 30 fun A.test() = a + b // 40일까? 50일까? } fun main() { B().apply { println(A().test()) } // 정답 : 40 } 확장함수가 외부에 있는 다른 클래스를 리시버로 받을 경우, 해당 함수가 어떻게 동작하는지 애매모호하게 됨 class A { var state = 10 } class B { var state = 20 fun A.update() = state + 10 // ..

KOTLIN 2022.07.27

[KOTLIN] 복잡한 객체를 생성하기 위한 DSL을 정의하라 (이펙티브 코틀린)

DSL Domain Specific Language의 약자로 특정 도메인에 국한해 사용하는 언어 코틀린을 통하여 DSL들을 접하는 경우가 많음 코틀린 DSL 예시 Gradle DSL plugins { 'java-library' } dependencies{ api("junit:junit:4.12") implementation("junit:junit:4.12") testImplementation("junit:junit:4.12") } configurations{ implementation{ resolutionStrategy.failOnVersionConflict() } } Test DSL class MyTests: StringSpec({ "반환되는 길이는 String의 크기이어야 합니다." { "test s..

KOTLIN 2022.07.20

[KOTLIN] 일반적인 프로퍼티 패턴은 프로퍼티 위임으로 만들어라 (이펙티브 코틀린)

프로퍼티 위임 코틀린에서 제공하는 관례에 의존하는 특성 중 하나 프로퍼티 위임을 사용하면 값을 뒷받침 하는 필드에 단순히 저장하는 것보다 더 복잡한 방식으로 작동하는 프로퍼티를 쉽게 구현 가능함 일반적인 프로퍼티의 행위를 추출해서 재사용이 가능함 프로퍼티 위임 예시 var token: String? = null get() { print("token returned value $field") return field } set(value) { print("token changed from $field to $value") field = value } var attempts: Int = 0 get() { print("attempts returned value $field") return field } set(..

KOTLIN 2022.07.13

[KOTLIN] 제네릭 타입과 VARIANCE 한정자를 활용하라 (이펙티브 코틀린)

제네릭 요약 참고 https://tgyun615.com/134?category=908821 [JAVA] 제네릭 제네릭 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정하는 방법 외부에서 사용자에 의해 타입이 지정되는 것을 의미 제네릭 장점 잘못된 타입이 들어올 수 있는 것을 tgyun615.com Variance 한정자 (out / in) class Box fun main(args: Array) { val box1: Box = Box() // OK!! val box2: Box = Box() // Compile Error!! } ---------------------------------------------- class Box fun main(args: Array) { val box1..

KOTLIN 2022.07.10

[KOTLIN] 타입 파라미터의 섀도잉을 피하라 (이펙티브 코틀린)

섀도잉 class User(val email: String) { fun isMatchingEmail(email: String): Boolean { ... } ... } 프로퍼티와 파라미터가 같은 이름을 가지게 되어, 지역 파라미터가 외부 스코프에 있는 프로퍼티를 가리게 되는 것을 섀도잉이라 함 그냥 프로퍼티와 파라미터가 같은 이름을 가질 수 있음으로 정의 interface Tree class Birch: Tree class Spruce: Tree class Forest { fun addTree(tree: T) { println("adding tree ...") } } fun main() { val forest = Forest() forest.addTree(Birch()) forest.addTree(Spr..

KOTLIN 2022.07.10

[KOTLIN] 연산자 오버로드를 할때는 의미에 맞게 사용

연산자 오버로딩 어떤 언어 기능과 미리 정해진 이름의 함수를 연결해주는 기법 (자바에서 Iterable 객체에 대해 for Loop를 사용할 수 있는 것 과 비슷함) 산술 연산자 오버로딩 자바는 원시 타입이 String에 대해서만 산술 연산자를 지원하지만 코틀린은 다른 클래스에서 산술연산자를 오버로딩하면 그대로 사용할 수 있음 이항 산술 연산자 오버로딩 data class Point(val x: Int, val y: Int) { operator fun plus(other: Point) : Point{ return Point(x + other.x, y + other.y) } } val p1 = Point(10, 20) val p2 = Point(30, 40) println(p1 + p2) // Point(..

KOTLIN 2022.07.03

[KOTLIN] NULLABLE UNIT 을 리턴하지 말라 (이펙티브코틀린)

코틀린 Unit, Nothing 타입 //Unit 예시 fun report() { // 아무것도 반환하지 않으면 return Unit 이 반환된다. } //Nothing 예시 //fail에서 Exception이 발생하면 user는 Nothing 타입이 됨 //Error: Type mismatch: inferred type is "User" but "Nothing?" was expected var user = if ( isPass() ) 42 else fail("Not Ready") Unit : 함수가 끝났으나 아무 것도 반환하지 않은 경우 Nothing : 함수가 끝이 나지 않은 경우 Unit을 리턴하면 안되는 이유 // Unit? 을 이용하는 경우 fun verifyKey(key: String): Un..

KOTLIN 2022.07.03

[KOTLIN] 변수의 스코프 최소화 (이펙티브코틀린)

이펙티브 코틀린 변수의 스코프 최소화 최대한 좁은 스코프를 갖게 변수를 사용하는 것이 좋음 반복문 내부에서만 변수가 사용된다면 변수를 반복문 내부에 작성하는 것이 좋음 스코프를 최소화하는 것이 좋은 이유 디버깅하기 수월 mutable 프로퍼티는 좁은 스코프에 걸쳐 있을수록 디버깅이 용이함 변수의 범위가 넓으면, 다른 개발자에 의해서 변수가 잘못 사용될 수 있음 변수는 읽기 전용 또는 읽고 쓰기 전용 여부와 상관 없이, 변수를 정의할 때 초기화되는 것이 좋음 if, when, try-catch, Elvis 표현식 등을 활용하면, 변수를 정의할 때 초기화할 수 있음 스코프 최소화 예시 // 나쁜 예 var user: User for (i in users.indices) { user = users[i] pri..

KOTLIN 2022.06.18