Kotlin
-
49장 - 하나 이상의 처리 단계를 가진 경우에는 시퀀스를 사용하라Kotlin/Effective Kotlin 요약 2023. 4. 13. 00:01
Iterable과 Sequence의 차이 interface Iterable { operator fun iterator() : Iterator } interface Sequence { operator fun iterator() : Iterator } 둘의 차이는 이름밖에 없는 것처럼 보입니다. 하지만 완전히 다른 목적으로 설계되어 있습니다. 서로 다른 filter 확장함수 구현 public inline fun Iterable.filter( predicate: (T) -> Boolean ): List{ return filterTo(ArrayList(), predicate) } public inline fun Sequence.filter( predicate: (T) -> Boolean ): List{ retu..
-
48장 - 더 이상 사용하지 않는 객체의 레퍼런스를 제거하라Kotlin/Effective Kotlin 요약 2023. 4. 12. 00:01
개요 보통 GC가 메모리 관리를 자동으로 해주기 때문에 객체의 해제를 따로 생각하지 않습니다. 하지만 메모리 관리를 전혀 신경 쓰지 않으면 메모리 누수가 발생하여 상황에 따라 OutOfMemoryError가 발생하기도 합니다. 따라서 ' 더 이상 사용하지 않는 객체의 레퍼런스를 유지하면 안 된다'라는 규칙 정도는 지켜 주는 것이 좋습니다. 안드로이드 개발자가 많이 하는 실수 Activity(데스크톱 애플리케이션의 창)을 여러 곳에서 자유롭게 접근하기 위해 companion 프로퍼티에 이를 할당해 두는 경우가 많습니다. 하지만 이렇게 되면 GC가 해당 객체에 대한 메모리를 해제할 수 없습니다. 액티비티는 굉장히 큰 객체로 큰 메모리 누수가 발생하게 됩니다. 책에서 보여주는 메모리 누수의 예시로는 compa..
-
47장 - 인라인 클래스의 사용을 고려하라Kotlin/Effective Kotlin 요약 2023. 4. 11. 00:01
개요 함수뿐만 아니라 클래스도 inline으로 만들 수 있습니다. inline 클래스 inline class Name(private val value: String){ //... } String을 name으로 래핑 해서 사용하고 있습니다. 하지만 inline을 활용하기 때문에 어떠한 오버헤드도 발생하지 않습니다. (inline으로 바로 호출해서 사용하기 때문에 래핑의 비용이 들지 않음) inline 클래스의 활용 보통 측청 단위를 표현할 때 타입 오용으로 발생하는 문제를 막을 때 측정 단위를 표현할 때 만약 time이라는 단어를 마주하면 이게 ms인지 s 인지 min인지 명확하지 않습니다. 가장 간단한 방법으로 파라미터 이름에 측정 단위를 붙여 줄 수 있습니다. 하지만 함수를 사용할 때 프로퍼티 이름이 ..
-
46장 - 함수 타입 파라미터를 갖는 함수에 inline 한정자를 붙여라Kotlin/Effective Kotlin 요약 2023. 4. 10. 00:01
개요 코틀린의 고차 함수(함수를 파라미터로 받는 함수 또는 함수를 리턴하는 함수)는 대부분 inline 한정자가 붙어있습니다. inline 한정자는 무엇일까요? inline 한정자 inline 한정자의 역할은 컴파일 시점에 '함수를 호출하는 부분'을 '함수의 본문'으로 대체합니다. 예를 들어 repeat 함수를 다음과 같이 구현되어 있습니다. inline fun repeat(times: Int, action: (Int) -> Unit){ for(index in 0 until times){ action(index) } } repeat을 호출하는 부분은 컴파일 시점 다음과 같이 대체됩니다. repeat(10){ println(it) } //컴파일 시점 for(index in 0 until 10){ print..
-
45장 - 불필요한 객체 생성을 피하라Kotlin/Effective Kotlin 요약 2023. 4. 8. 00:01
객체 생성의 비용 객체 생성은 언제나 비용이 들어갑니다. JVM에서는 하나의 가상 머신에서 동일한 문자열을 처리하는 코드가 여러 개 있다면, 기존의 문자열을 재사용합니다. 또한 Int는 -128 ~ 127 범위를 캐시해 둡니다. 객체 생성 비용은 항상 클까? 현재 64비트 JDK에서 객체는 8바이트의 배수만큼 공간을 차지합니다. 앞부분 12바이트는 헤더로서 반드시 있어야 하므로, 최소 크기는 16바이트입니다. 기본 자료형 int는 4바이트입니다. 하지만 오늘날 널리 사용되고 있는 64비트 JDK에 랩 되어 있는 Integer는 16바이트입니다. 추가로 이에 대한 레퍼런스로 인해 8바이트가 더 필요해 5배 이상의 공간을 차지한다고 볼 수 있습니다. 객체는 생성되어야 하며, 메모리 영역에 할당되고, 이에 대..
-
44장 - 멤버 확장 함수의 사용을 피하라Kotlin/Effective Kotlin 요약 2023. 4. 7. 00:01
확장 함수를 멤버 함수로 정의 어떤 클래스에 대한 확장 함수를 정의할 때, 이를 멤버로 추가하는 것은 좋지 않습니다. 예를 들어 클래스 내부에 멤버로 정의할 수 있습니다. class PhoneNumberIncorrect{ fun String.isPhoneNumber(): Boolean = length == 7 && all {it.isDigit()} } fun main() { println(PhoneNumberIncorrect().apply {"1234567890".isPhoneNumber()}) } 확장 함수의 가시성 제한 private fun String.isPhoneNumber(): Boolean = length == 7 && all {it.isDigit()} fun main() { println("..
-
43장 - API의 필수적이지 않은 부분을 확장 함수로 추출하라Kotlin/Effective Kotlin 요약 2023. 4. 6. 00:01
메서드 VS 확장함수 클래스의 메서드를 정의할 때는 메서드를 멤버로 정의할 것이지 아니면 확장함수로 정의할 것인지 결정해야 합니다. 두 방식 중에 어떤 방식이 우월하다고 할 수 없습니다. 장단점을 비교하여 상황에 맞게 사용해야 합니다. 메서드로 정의하기 class Workshop(){ fun makeEvent(text: String){ println("make Event $text") } } fun main() { val workshop = Workshop() workshop.makeEvent("1") //make Event 1 } 확장 함수로 정의하기 class Workshop(){} fun Workshop.makeEvent(text: String){ println("make Event $text") ..
-
42장 - compareTo 규약을 지켜라Kotlin/Effective Kotlin 요약 2023. 4. 5. 00:01
compareTo 메서드 compareTo는 Any클래스에 있는 메서드는 아닙니다. 수학적인 부등식으로 변환되는 연산자입니다. fun main() { val str1 = "a" val str2 = "b" println(str1 > str2) //str1.compareTo(str2) > 0 println(str1 = str2) //str1.compareTo(str2) >= 0 println(str1 = a 라면 a==b이어야 한다. 연속적 동장 a >=b 이고 b>=c 라면 a>=c여야 한다. 그렇지 않다면 무한 반복에 빠질 수 있다. 코네스적 동작 두 요소는 확실한 관계를 가지고 있어야 합니다. a>=b 또는 b>=a..