Chapter 6. 코틀린 타입 시스템
6.1 널 가능성
6.1.1 널이 될 수 있는 타입
타입 이름 뒤에 물음표(?) -> null 참조를 저장할 수 있다는 뜻
6.1.2 타입의 의미
타입: 어떤 값들이 가능한지와 그 타입에 대해 수행할 수 있는 연산의 종류를 결정
6.1.3 안전한 호출 연산자: ?.
?. : null 검사와 메소드 호출을 한 번의 연산으로 수행
s?.toUpperCase() // if (s != null) s.toUpperCase() else null 과 같음
6.1.4 엘비스 연산자: ?:
엘비스 연산자(?:) : null 대신 사용할 디폴트 값을 지정할 때 사용하는 연산자
fun foo(s: String?) {
val t: String = s ?: "" // "s"가 null이면 결과는 빈 문자열
}
// 엘비스 연산자를 활용해 널 값 다루기
fun strLenSafe(s: String?) : Int = s?.length ?: 0
println(strLenSafe("abc")) // 3
println(strLenSafe(null)) // 0
6.1.5 안전한 캐스트: as?
as?: - 어떤 값을 지정한 타입으로 캐스트하는데, 값을 대상 타입으로 변환할 수 없으면 null을 반환
6.1.6 널 아님 단언: !!
!! : null이면 NullPointerException 발생, 어떤 값이든 널이 될 수 없는 타입으로 강제로 바꿈
6.1.7 let 함수
foo?.let { ...it... }
1) foo != null => it은 람다 안에서 널이 아니다.
2) foo == null => 아무 일도 일어나지 않는다.
// let을 사용해 null이 아닌 인자로 함수 호출하기
fun sendEmailTo(email: String) {
println("Sending email to $email")
}
var email: String? = "[email protected]"
email?.let { sendEmailTo(it) } // Sending email to [email protected]
email = null
email?.let { sendEmailTo(it) } // 아무일도 x
6.1.8 나중에 초기화할 프로퍼티
lateinit 변경자 : 프로퍼티를 나중에 초기화할 수 있음, 해당 프로퍼티는 항상 var이어야 함.
6.1.9 널이 될 수 있는 타입 확장
6.1.10 타입 파라미터의 널 가능성
6.1.11 널 가능성과 자바
@Nullable + Type = Type?
@NotNull + Type = Type
[플랫폼 타입]
: 널 관련 정보를 알 수 없는 타입 => 널이 될 수 있는 타입으로 처리해도 되고, 널이 될 수 없는 타입으로 처리해도 됨
- 자바 타입은 코틀린에서 플랫폼 타입으로 표현됨
[상속]
코틀린에서 자바 메소드를 오버라이드할 때 그 메소드의 파라미터와 반환 타입을 널이 될 수 있는 타입으로 선언할지 널이 될 수 없는 타입으로 선언할지 결정해야 함
6.2 코틀린의 원시 타입
6.2.1 원시 타입: Int, Boolean 등
코틀린은 원시 타입과 래퍼 타입을 구분하지 않음
6.2.2 널이 될 수 있는 타입: Int?, Boolean? 등
6.2.3 숫자 변환
코틀린은 한 타입의 숫자를 다른 타입의 숫자로 자동 변환하지 x
val i = 1
val l: Long = i // 컴파일 오류 발생
val i = 1
val l: Long = i.toLong() // 변환 함수 사용
=> 명시적 변환이 필요
- 숫자 리터럴 사용할 때는 변환 함수 필요 x
- 산술 연산자를 사용할 때도 변환 필요 x
fun foo(l: Long) = println(l)
val b: Byle = l
val l = b + 1L
foo(42) // 42
6.2.4 Any, Any?: 최상위 타입
Any 타입 : 모든 널이 될 수 없는 타입의 조상 타입(원시 타입을 포함한 모든 타입의 조상 타입)
- Object에 있는 다른 메소드를 호출하고 싶다면 Any에서 Object타입으로 값을 캐스트 해야 함.
6.2.5 Unit 타입: 코틀린의 void
Unit 타입: 자바 void와 같은 기능
- void와 다른 점 - 모든 기능을 갖는 일반적인 타입 -> 타입 인자로 쓸 수 있음
6.2.6 Nothing 타입: 이 함수는 결코 정상적으로 끝나지 않는다
Nothing 타입 - 아무 값도 포함하지 않음
fun fail(message: String) : Nothing {
throw IllegalStateException(message)
}
val address = company.address ?: fail("No address")
println(address.city)
6.3 컬렉션과 배열
6.3.1 널 가능성과 컬렉션
List<Int?> : 리스트 안의 각 값이 널이 될 수 있음
List<Int>? : 전체 리스트가 널이 될 수 있음
컬렉션.filterNotNull() : 널이 될 수 있는 값으로 이뤄진 컬렉션에서 널 값을 걸러내는 함수
6.3.2 읽기 전용과 변경 가능한 컬렉션
Collection : 읽기 전용 컬렉션
MutableCollection : 변경 가능한 컬렉션
6.3.3 코틀린 컬렉션과 자바
[컬렉션 생성 함수]
컬렉션 타입 | 읽기 전용 타입 | 변경 가능 타입 |
List | listOf | mutableListOf, arrayListOf |
Set | setOf | mutableSetOf, hashSetOf, linkedSetOf, sortedSetOf |
Map | mapOf | mutableMapOf, hashMapOf, linkedMapOf, sortedMapOf |
6.3.4 컬렉션을 플랫폼 타입으로 다루기
- 컬렉션이 널이 될 수 있는가?
- 컬렉션의 원소가 널이 될 수 있는가?
- 오버라이드하는 메소드가 컬렉션을 변경할 수 있는가?
6.3.5 객체의 배열과 원시 타입의 배열
코틀린에서 배열을 만드는 방법
- arrayOf 함수에 원소를 넘기기
- arrayOfNulls 함수에 정수 값을 인자로 넘기면 모든 원소가 null이고 인자로 넘긴 값과 크기가 같은 배열 만듦
- Array 생성자는 배열 크기와 람다를 인자로 받아서 람다를 호출해서 각 배열 원소를 초기화
val letters = Array<String>(26) { i -> ('a' + i ).toString() }
println(letters.joinToString(""))
toTypedArray() : 컬렉션을 배열로 바꿔줌
[원시 타입의 배열을 만드는 방법]
- 각 배열 타입의 생성자는 size 인자를 받아서 해당 원시 타입의 디폴트 값으로 초기화 된 size 크기의 배열 반환
- 팩토리 함수 (예: intArrayOf 등)는 여러 값을 가변 인자로 받아서 그런 값이 들어간 배열을 반환
- 크기와 람다를 인자로 받는 생성자를 사용
Author And Source
이 문제에 관하여(Chapter 6. 코틀린 타입 시스템), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@rosesua318/Chapter-6.-코틀린-타입-시스템저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)