티스토리 뷰
공변,무공변,반공변에 대한 개념들은
"타입 S가 T의 하위타입이면 List<S>도 List<T>의 하위타입인가?"에 대한 질문으로 시작한다.
<무공변> 타입 S가 T의 하위 타입일때 -> Box<S>와 Box<T>가 어떤 관계도 아닌 경우
<공변>: 타입 S가 T의 하위 타입일때 -> Box<S>가 Box<T>의 하위타입인 경우
<반공변>: 타입 S가 T의 상위 타입일때 -> Box<S>가 Box<T>의 상위타입인 경우
- 일반적으론 무공변이다.
- List<Object>랑 List<String>은 어떤 관계도 없다.
- 왜그러냐면, 제네릭은 "타입소거"방식으로 동작한다.
- 타입소거란? 컴파일시에만 타입 검사를 하고 런타임시에는 제네릭의 인스턴스에 대한 타입정보를 갖고 있지 않는 것
- 예를 들어) List<String>은 런타임시에는 그냥 List로 간주된다.
(개발자눈에만 타입이 보인다는뜻) - 그래서 is 키워트로 List의 타입 체크를 할 수가 없음
if (value is List<String>) {...}
// ERROR : Cannot check for instance of erased type
- 공변은 <out T>키워드로, 반공변은 <in T>키워드를 사용
- 공변(out)
- 자기자신이나 자식의 클래스를 타입으로 받을 수 있음
- 반공변(in)
- 자기자긴이나 부모 클래스를 타입으로 받을 수 있음
실 코드의 예
sealed class CommonResult<out T>{
class Success<T>(val value: T) : CommonResult<T>()
class Error(val exception: Exception) : CommonResult<Nothing>()
object Loading : CommonResult<Nothing>()
}
fun <T, R> CommonResult<T>.map(transform: (T) -> R): CommonResult<R> {
return when (this) {
is CommonResult.Success -> {
try {
CommonResult.Success(transform(value))
} catch (e: Exception) {
CommonResult.Error(e)
}
}
else -> {
CommonResult.Loading
}
}
}
out을 빼면 에러남
→CommonResult.Error에서 문제가 발생함
왜냐 CommonResult.Error의 타입은 CommonResult<Nothing>이다.
map함수의 리턴값은 CommonResult<R>이다.
Nothing은 R의 자식이므로 out을 붙여야함
내가 헷갈렸던 점
- CommonResult sealed class에서는 CommonResult.Error의 타입은 CommonResult<Nothing>인것
코드
참고
- 코틀린으로 배우는 함수형 프로그래밍 책
'개발 > 코틀린' 카테고리의 다른 글
코틀린 코루틴 내부 동작 이해하기 (0) | 2023.12.28 |
---|
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- #우분투
- 코틀린으로배우는함수형프로그래밍
- 공변
- databinding
- stateflow
- 다이나믹링크
- 코루틴동시성프로그래밍
- 코틀린코루틴
- 프로그래머스
- Hilt
- #EC2
- 코틀린
- Android
- 반공변
- Kotlin
- 안드로이드
- 변성
- 키보드
- dynamiclink
- c++
- 자바
- 힐트
- 코루틴내부동작
- #tensorflow
- 코루틴딥다이브
- 코틀린코루틴스터디
- 코루틴
- TF-Slim
- #윈도우
- 무공변
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함