1. 널 가능성
- NullPointerException 오류를 피할 수 있게 돕기 위한 코틀린 타입 시스템의 특성
- 실행시점 → 컴파일시점 감지
1-1. 널이 될 수 있는 타입
- 널을 인자로 받을 수 있도록 변경 : 타입이름 뒤 ?를 명시한다.
- 따라서, 모든 타입은 기본적으로 널이 될 수 없는 타입이다.
- 널이될 수 있는 타입은 null값을 다루어야 한다!
fun strLenSafe(s: String?): Int = if (s != null) s.length else 0
fun strLenSafe(s: String?): Int = if (s != null) s.length else 0
1-2. 안전한 호출 연산자 ?.
foo?.bar()
- foo가 null이 아닐 때, 정상 실행 foo.bar()
- foo가 null일 때, null 반환
- 에러가 발생하지 않는다.
1-3. 엘비스 연산자 ?:
- 좌항이, null이 아니면 좌항반환
- 좌항이, null이면 우항반환
fun strLenSafe(s: String): Int = s.length ?: 0
1-4. 안전한 캐스트 as?
as : 지정한 타입으로 바꿀 수 없으면 ClassCastException이 발생한다.
as? : 지정한 타입으로 바꿀 수 없으면 null을 반환한다.
1-5. null 아님 단언 !!
널이 될 수 없는 타입으로 강제로 바꾼다.
1-6. let 함수
null이 될 수 있는 식을 쉽게 다룰 수 있다.
- String을 파라미터로 받는 함수 A
- null이 될 수 있는 타입 String? 은 함수 A의 인자로 전달할 수 없다. 사용하려면,
fun A(email: String) { }
// 1. let 사용X. 검증해주고 넣어야 한다.
if (email != null) A(email)
// 2. let 사용. String? 에서 String 타입으로 변환하여 사용
email?.let { A(it) } // ?. 을 사용하여 안전한 호출
1-7. 나중에 초기화할 프로퍼티 lateinit
class MyService {}
class MyTest {
private lateinit var myService: MyService
@Before fun setUp() {
myService = MyService()
}
}
1-8. null이 될 수 있는 타입 확장
null이 될 수 있는 수신객체에 대해 확장 함수 호출할 수 있다.
fun String?.isNullOrBlank(): Boolean = this == null || this.isBlank()
1-9. 타입 파라미터의 null 가능성
T는 Any? 타입이다.
fun <T> printHashCode(t: T) {
println(t?.hashCode()) // null이 될 수 있으므로 안전하게 호출
}
fun <Any> printHashCode(t: T) {
println(t.hashCode()) // null이 들어올 수 없다.
}
2. 코틀린의 원시타입
2-1. 원시타입
원시타입(primitive type) : Int, Boolean
- 값이 직접 들어감
참조타입(reference type) : String
- 메모리상의 객체 위치가 들어감
- 자바는 원시타입을 컬렉션에 담을 수 없다. 래퍼타입으로 원시타입을 감싸 사용한다. Collection<Integer> 처럼 사용해야 한다.
- 코틀린은 원시타입과 래퍼타입을 구분하지 않는다. 항상 같은 타입을 사용한다.
2-2. 널이 될 수 있는 원시타입 Int? Boolean? …
자바의 래퍼 타입으로 컴파일된다.
2-3. 숫자 변환
자바처럼 숫자가 자동변환 하지 않는다.
val i = 1
val l: Long = i.toLong()
개발자의 혼란을 피할 수 있다. 명시적으로 변환하자
2-4. 최상위타입 Any, Any?
자바의 최상위 타입 : Object
- 참조타입만
코틀린의 최상위 타입 : Any
- 원시타입을 포함한 모든 타입조상
- 참조타입이지만, 원시타입을 대입하면 객체로 감싼다.
2-5. 코틀린의 void Unit타입
코틀린의 Unit타입은 자바의 void와 같은 기능이다.
fun f(): Unit { ... }
fun f() { ... } // 같다
- 단, Unit을 타입인자로 쓸 수 있다. (void와 차이점)
- class NoResultProcessor: Processor<Unit> { override fun process() { // return할 필요 없다. } }
2-6. 이 함수는 결코 정상적으로 끝나지 않는다 Nothing 타입
코틀린에는 결코 성공적으로 값을 돌려주는 일이 없어 반환값이라는 개념이 의미 없는 함수가 일부 존재한다.
- 테스트 라이브러리의 fail함수를 제공하는 경우 (테스트 실패)
- 무한 루프 함수
fun fail(message: String): Nothing {
throw IlleagalStateException(message)
}
3. 컬렉션과 배열
3-1. 널 가능성과 컬렉션
- List<Int?> : 리스트 안의 각 값이 널이될 수 있다.
- List<Int>? : 전체 리스트가 널이될 수 있다.
- List<Int?>? : 이렇게 사용할수도 있다.
3-2. 읽기전용 컬렉션, 변경가능한 컬렉션
Collection
- 원소 추가, 제거 메서드가 없다
MutableCollection
- add
- remove
- clear
가능하면 항상 읽기 전용 인터페이스를 사용하는 것을 일반적인 규칙으로 삼자.
kotlin in action 책을 통한 공부입니다.
'공부 > Kotlin' 카테고리의 다른 글
[Kotlin] 파라미터와 반환 값으로 람다 사용해보기 (0) | 2022.07.02 |
---|---|
[Kotlin] 연산자 오버로딩과 기타 관례 사용해보기 (0) | 2022.06.20 |
4장. 클래스, 객체, 인터페이스 (0) | 2022.06.07 |
3장. 함수 정의와 호출 (0) | 2022.06.07 |
2장. 코틀린 기초 (0) | 2022.05.29 |
댓글