Notice
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 안드로이드 유닛 테스트
- 스택 큐 차이
- rxjava disposable
- 클래스
- jvm 작동 원리
- rxjava hot observable
- 객체
- 안드로이드 라이선스
- 큐 자바 코드
- 안드로이드 유닛테스트란
- android ar 개발
- 안드로이드 라이선스 종류
- 2022 플러터 안드로이드 스튜디오
- ar vr 차이
- 2022 플러터 설치
- jvm이란
- ANR이란
- 서비스 쓰레드 차이
- 자바 다형성
- android retrofit login
- 멤버변수
- 안드로이드 레트로핏 crud
- 안드로이드 유닛 테스트 예시
- 안드로이드 레트로핏 사용법
- rxjava cold observable
- 스택 자바 코드
- Rxjava Observable
- 서비스 vs 쓰레드
- 플러터 설치 2022
- 안드로이드 os 구조
Archives
- Today
- Total
나만을 위한 블로그
[이펙티브 코틀린] 아이템 44. 멤버 확장 함수의 사용을 피하라 본문
728x90
반응형
어떤 클래스에 대한 확장 함수를 정의할 때 이를 멤버로 추가하는 건 옳지 않다. 확장 함수는 첫 번째 아규먼트로 리시버를 받는 단순한 일반 함수로 컴파일된다. 아래 함수는 그 아래 함수로 컴파일된다.
fun String.isPhoneNumber(): Boolean = length == 7 && all { it.isDigit() }
fun isPhoneNumber('$this': String): Boolean =
'$this'.length == 7 && '$this'.all { it.isDigit() }
이렇게 단순하게 변환되기 때문에 확장 함수를 클래스 멤버로 정의할 수도 있고 인터페이스 안에 정의할 수도 있다.
interface PhoneBook {
fun String.isPhoneNumber(): Boolean
}
class Fizz: PhoneBook {
override fun String.isPhoneNumber(): Boolean =
length == 7 && all { it.isDigit() }
}
이런 코드가 가능하지만 DSL을 만들 때를 제외하면 안 쓰는 게 좋다. 특히 가시성 제한을 위해 확장 함수를 멤버로 정의하는 건 굉장히 좋지 않다. 큰 이유는 가시성을 제한하지 못한다는 것이다. 이는 단순하게 확장 함수를 쓰는 형태를 어렵게 만들 뿐이다.
확장 함수의 가시성을 제한하고 싶다면 멤버로 만들지 말고 가시성 한정자를 붙인다. 멤버 확장을 피해야 하는 이유를 정리하면 아래와 같다.
- 레퍼런스를 지원하지 않는다
- 암묵적 접근을 할 때 두 리시버 중 어떤 리시버가 선택될지 혼동된다
- 확장 함수가 외부의 다른 클래스를 리시버로 받을 때 해당 함수가 어떤 동작을 하는지 명확하지 않다
- 경험 적은 개발자의 경우 확장 함수를 보면 직관적이지 않을 수 있다
반응형
'책 > Effective Kotlin' 카테고리의 다른 글
[이펙티브 코틀린] 아이템 46. 함수 타입 파라미터를 갖는 함수에 inline 한정자를 붙여라 (0) | 2023.05.05 |
---|---|
[이펙티브 코틀린] 아이템 45. 불필요한 객체 생성을 피하라 (0) | 2023.04.29 |
[이펙티브 코틀린] 아이템 43. API의 필수적이지 않은 부분을 확장 함수로 추출하라 (0) | 2023.03.29 |
[이펙티브 코틀린] 아이템 42. compareTo의 규약을 지켜라 (0) | 2023.03.26 |
[이펙티브 코틀린] 아이템 41. hashCode의 규약을 지켜라 (0) | 2023.03.20 |
Comments