분류 전체보기 121

아이템22) 일반적인 알고리즘을 구현할 때 제네릭을 사용하라

타입 아규먼트를 사용하는 함수를 제네릭 함수라고 부름stdlib에 있는 filter 함수가 있음inline fun Iterable.filter(predicate: (T) -> Boolean): List { val destination = ArrayList() for (element in this) { if (predicate(element)) { destination.add(element) } } return destination}타입 파라미터는 컴파일러에게 타입과 관련된 정보를 제공하여 컴파일러가 타입을 조금 더 정확하게 추측할 수 있게 해줌filter 함수에서 컴파일러가 아규먼트가 컬렉션의 요소와 같은 타입이라는 것을 알 수 있으므로 잘못 처리하는 것을 막을 수 있음제네릭은 기본적으로 Lis..

아이템21) 일반적인 프로퍼티 패턴은 프로퍼티 위임으로 만들어라

코틀린은 코드 재사용과 과련해서 프로퍼티 위임이라는 새로운 기능을 제공프로퍼티 위임을 사용하면 일반적인 프로퍼티의 행위를 추출해서 재사용 가능대표적인 예로 지연 프로퍼티가 있음lazy 프로퍼티는 처음 사용하는 요청이 들어올 때 초기화되는 프로퍼티를 의미코틀린에서는 프로퍼티 위임을 활용해 간단하게 구현할 수 있음stdlib는 lazy프로퍼티 패턴을 쉽게 구현할수 있는 함수 제공val value by lazy { createValue() }변화가 있을 때 감지하는 observable 패턴을 쉽게 만들 수 있음stdlib의 observable 델리게이트를 기반으로 간단하게 구현할 수 있음var items: List by Delegates.observable(listOf()) { _, _, _ -> notifi..

아이템20) 일반적인 알고리즘을 반복해서 구현하지 말라

많은 개발자는 같은 알고리즘을 여러 번 반복해서 구현 수학적인 연산, 수집 처리처럼 별도의 모듈 또는 라이브러리로 분리할 수 있는 부분을 의미 숫자를 특정 범위에 맞추는 간단한 알고리즘 val percent = when { numberForUser > 100 -> 100 numberForUser else -> numberForUser } stdlib의 coerceIn 확장 함수로 이미 존재 val percent = numberFromUser.coerceIn(0, 100) 이미 있는 것을 활용하면 다양한 장점이 있음 코드 작성 속도가 빨라짐 알고리즘을 만드는 것보다 빠름 구현을 따로 읽지 않아도, 함수의 이름 등만 보고도 무엇을 하는지 확실하게 알 수 있음 처음 보더라도 한 번 보고 나면, 그..

아이템19) knowledge를 반복하여 사용하지 말라

프로그래밍의 가장 큰 규칙 👉 프로젝트에서 이미 있던 코드를 복사해서 붙여넣고 있다면, 무언가가 잘못된 것이다 knowledge를 반복하여 사용하지 말라는 규칙으로 표현 knowledge knowledge는 넓은 의미로 ‘의도적인 정보’를 뜻함 knowledge는 코드 또는 데이터로 표현할 수 있음 기본 동작을 하게 아예 코드와 데잍를 부족하게 만들어서도 표현할 수 있음 상속을 하는데도 불구하고 특정 메서드를 오버라이드하지 않게 강제하는 것은 ‘해당 메서드가 슈퍼클래스와 동일하게 동작하기 원한다’는 의미 knowledge 종류는 다양함 알고리즘의 작동 방식 UI의 형태 우리가 우너하는 결과 knowledge는 어떤 도구, 가상머신, 다른 프로그램들에서 직접 또는 간접적으로 이해할 수 있는 정보 프로그래밍..

아이템18) 코딩 컨벤션을 지켜라

코틀린은 잘 정리된 코딩 컨벤션을 가지고 있음 코틀린 문서의 Coding Convensions 참고 컨벤션을 최대한 지켜주는 것이 좋음 어떤 프로젝트를 접해도 쉽게 이해할 수 있음 다른 외부 개발자도 프로젝트의 코드를 쉽게 이해할 수 있음 다른 개발자도 코드의 작동 방식을 쉽게 추측할 수 있음 코드를 병합하고, 프로젝트의 코드 일부를 다른 코드로 이동하는 것이 쉬움 컨벤션을 지킬 때 도움이 되는 두 가지 도구가 있음 IntelliJ Formatter: 공식 코딩 컨벤션 스타일에 맞춰서 코드를 변경해 줌 settings → Editor → Code Style → Kotlin 에서 ‘Set from…’ 링크 클릭 ‘Predefined style/Kotlin style guide’ 선택 ktlint: 많이 사..

아이템17) 이름 있는 아규먼트를 사용하라

코드에서 아규먼트의 의미가 명확하지 않은 경우가 있음 “|”은 무엇을 의미할까? joinToString에 대해서 알지 못하면 “|”에 대한 의미를 알기 어려움 val text = (1..10).joinToString("|") 파라미터가 명확하지 않은 경우에 직접 지정해서 명확하게 만들어 줄수 있음 val text = (1..10).joinToString(separator = "|") 변수를 사용해 의미를 명확하게 할 수 있음 실제로 코드에서 제대로 사용되고 있는지 알수 없는 단점 val separator = "|" val text = (1..10).joinToString(separator) 이름 있는 아규먼트를 함께 활용 하는 것이 좋음 변수를 잘못 만들어 사용 하는 경우 방지 잘못된 위치에 배치 하는 ..

아이템16) 프로퍼티는 동작이 아니라 상태를 나타내야 한다

코틀린의 프로퍼티는 자바의 필드와 비슷해보이지만 서로 다른 개념 // 코틀린의 프로퍼티 var name: String? = null // 자바의 필드 String name = null; 둘다 데이터를 저장 코틀린 프로퍼티에는 더 많은 기능이 있음 사용자 정의 세터와 게터를 가질 수 있음 var name: String? = null get() = field?.toUpperCase() set(value) { if (!value.isNullOrBlank()) { field = value } } field 식별자는 프로퍼티의 데이터를 저장해 두는 백킹 필드에 대한 레퍼런스 세터와 게터의 디폴트 구현에 사용되므로, 따로 만들지 않아도 디폴트로 생성 val을 사용해서 읽기 전용 프로퍼티를 만들 대는 field가 만..

아이템15) 리시버를 명시적으로 참조하라

이펙티브 코루틴을 요약한 내용입니다 명시적으로 긴 코드를 사용할 때가 있음 함수와 프로퍼티를 지역 또는 톱레벨 변수가 아닌 다른 리시버로부터 가져온다는 것을 나타낼 때 class User: Person() { private var beersDrunk: Int = 0 fun drinkBeers(num: Int) { this.beersDrunk += num } } 확장 리시버를 명시적으로 참조하게 할 수 있음 리시버를 명시적으로 표시하지 않은 퀵소트 구현 fun List.quickSort(); List { if (size < 2) { return this } val pivot = first() val (smller, bigger) = drop(1).partition { it < pivot } return s..

아이템14) 변수 타입이 명확하지 않은 경우 확실하게 지정하라

이펙티브 코루틴을 요약한 내용입니다 코틀린은 수준 높은 타입 추론 시스템을 갖추고 있음 val num = 10 val name = "Marcin" val ids = listOf(12, 112, 554, 997) 유형이 명확하지 않을 때는 남용하면 좋지 않음 val data = getSomeData() 가독성을 위해 코드를 설계할 때 읽는 사람에게 중요한 정보를 숨겨서는 안됨 코드 정의로 쉽게 이동할 수 없는 Github 등이 환경에서 코드를 읽을 수도 있음 타입을 지정해주면 코드를 쉽게 읽을 수 있음 val data: UserData = getSomeData() 가독성 향상 이외에 안전을 위해서도 타입을 지정하는 것이 좋음 타입은 개발자와 컴파일러 모두에게 중요한 정보

아이템13) Unit?을 리턴하지 말라

이펙티브 코루틴을 요약한 내용입니다 함수에서 Unit?을 리턴한다면, 그 이유는 무엇일까요? Boolean이 true또는 false를 갖는 것처럼, Unit?은 Unit 또는 null이라는 값을 가질 수 있음 Boolean과 Unit? 타입은 서로 바꿔서 사용할 수 있음 Boolean으로 사용한 코드 fun keyIsCorrect(key: String): Boolean = //... if (!keyInCorrect(key)) return Unit?으로 사용하는 경우 fun verifyKey(key: String): Unit? = //... verifyKey(key) ?: return 코드를 작성할 떄는 멋있게 보일 수도 있겠지만, 읽을 때는 그렇지 않음 Unit?으로 Boolean을 표현하는 것은 오해의..