null 허용
val a : String // 에러 : 초기화를 반드시 해야 함
val a : String = null // 에러 : 코틀린은 기본적으로 Null을 허용하지 않음
val a : String? = null // OK 자료형 오른쪽에 ? 기호를 붙여주면 null값 허용
lateinit 키워드로 늦은 초기화
- 변수 앞에 추가해주면 특정 타이밍에 객체를초기화 할수 있다. 단, 초기화를 잊는다면 잘못된 null 값을 참조하여 앱이 종료할 수 있다.
lateinit var a : String // OK
a = "hello"
println(a) // hello
- var 변수에서만 사용한다.
- null 값으로 초기화 할 수 없다.
- 초기화 전에는 변수를 사용할 수 없다.
- Int, Long, Double, Float에서는 사용할 수 없다.
lazy로 늦은 초기화
- val 선언 뒤에 by lazy 블록에 초기화에 필요한 코드를 작성한다. 마지막 줄에는 초기화할 값을 작성한다. str이 처음 호출될 때 초기화 블록의 코드가 실행된다. println() 메서드로 두 번 호출하면 처음에만 "초기화"가 출력된다.
val str : String by lazy {
println("초기화")
"hello" // 초기화 할 값
}
println(str) // 초기화; hello
println(str) // hello
- val에서만 사용한다.
- 조건이 적기 때문에 상대적으로 lateinit 보다 편하게 사용할 수 있다.
null값이 아님을 보증(!!)
변수 뒤에 !!를 추가하면 null 값이 아님을 보증하게 된다. 코드 작성할 때 null 이여도 빨간줄은 안뜨지만 변수의 값이 null인 경우 에러가 뜰 수 있음
val name : String? = "키다리"
val name2 : String = name // 에러
val name3 : String? = name // OK
val name4 : String = name!! // OK
- 좋은 방법은 아니라고..
안전한 호출( ?. )
- 메서드 호출 시 점 . 연산자 대신 ?. 연산자를 사용하면 null 값이 아닌 경우에만 호출된다. if문 줄일 수 있다.
val str : String? = null
var upperCase = if (str != null) str else null // null
upperCase = str?.toUpperCase // null 위에 것과 같은 뜻임
엘비스 연산자( ?: )
- 안전한 호출 시 null이 아닌 기본값을 반환하고 싶을 떄는 엘비스 연산자를 함께 사용한다.
val str : String? = null
var upperCase = if (str != null) str else null // null
upperCase = str?.toUpperCase ?: "초기화하시오" // 초기화하시오
컬렉션
- 개발에 유용한 자료구조. 리스트나 맵 등이 있음.
리스트
- 배열처럼 같은 자료형의 데이터들을 순서대로 가지고 있는 자료구조이다. 중복된 아이템을 가질 수 있고 추가, 삭제, 교체 등이 쉽다.
- 요소를 변경할 수 없는 읽기 전용 리스트는 listOf() 메서드로 작성할 수 있다.
val foods : List<String> = listOf("라면", "갈비", "밥") // 읽기 전용으로 추가, 삭제 안됨
- 요소를 변경하는 리스트를 작성할 때는 mutableListOf() 메서드를 사용한다. 자바와 다른 점은 특정 요소에 접근할 때 대괄호 안에 요소 번호로 접근할 수 있다는 것이다.
val foods = mutableListOf ("라면", "갈비", "밥")
foods.add("초밥") // 초밥을 맨 뒤에 추가
foods.removeAt(0) // 맨 앞의 아이템 삭제
foods[1] = "부대찌개" // foods.set(1, "부대찌개") (1번째 아이템을 부대찌개로 변경)
println(foods) // [갈비, 부대찌개, 초밥]
println(foods[0]) // 갈비
맵
- 키와 값(value)의 쌍으로 이루어진 키가 중복될 수 없는 자료구조이다. 리스트와 마찬가지로 mapOf() 메서드로 읽기 전용 맵을 만들 수 있고, mutableMapOf() 메서드로 수정이 가능한 맵을 만들 수 있다. 맵의 요소에 접근할 때는 대괄호 안에 키를 요소명으로 작성하여 접근한다.
// 읽기 전용 맵
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
// 변경 가능한 맵
val citiesMap = mutableMapOf("한국" to "서울",
"일본" to "동경",
"중국" to "북경")
// 요소에 덮어쓰기
citiesMap["한국"] = "서울특별시"
// 추가
citiesMap["미국"] = "워싱턴"
// 맵의 키와 값을 탐색
for ((k, v) in map) {
println("$k -> $v")
}
집합
- 중복되지 않은 요소들로 구성된 자료구조. setOf() 메서드로 읽기 전용 집합을, mutableSetOf() 메서드로 수정 가능한 집합을 생성한다. 집합은 리스트, 맵과 함께 대표적인 기본 자료구조이다.
// 읽기 전용 집합
val citySet= setOf("서울", "수원", "부산")
// 수정 가능한 집합
val citySet2 = mutableSetOf("서울", "수원", "부산")
citySet2.add("안양") // [서울, 수원, 부산, 안양]
citySet2.remove("수원") // [서울, 부산, 안양]
// 집합의 크기
println(citySet2.size) // 3
// '서울'이 집합에 포함되었는지
println(citySet2.contains("서울")) // true
람다식
- 자바8과 같이 람다식을 지원. 람다식은 하나의 함수를 표현하는 방법으로 익명 클래스나 익명 함수를 간결하게 표현할 수 있어서 매우 유용함. 코드를 간결하게 해주는 장점이 있지만 디버깅이 어렵고 남발할 경우 오히려 코드 가독성이 떨어져 주의하여 사용해야 한다.
fun add ( x : Int, y : Int ) : Int {
return x + y
}
fun add (x : Int, y : Int) = x + y
var add = { x : Int, y : Int -> x + y } // 람다식 표현
println(add(2, 5)) // 7
SAM 변환
- 코틀린에서는 추상 메서드 하나를 인수로 사용할 때는 함수를 인수로 전달하면 편하다. 자바로 작성된 메서드가 하나인 인터페이스를 구현할 때는 대신 함수를 작성할 수 있다. 이를 SAM 변환이라고 한다.
button.setOnClickListener ( object : View.OnClickListener {
override fun onClick ( v : View? ) {
// 클릭 시 처리
}
})
// 람다식으로 간단하게 처리 가능!!
button.setOnClickListenr ( { v : View? ->
// 클릭 시 처리
} )
// 메서드 호출 시 맨 뒤에 전달되는 인수가 람다식인 경우에는 람다식을 괄호 밖으로 뺄 수 있다.
button.setOnClickListener() { v : View? ->
// 클릭 시 처리
}
// 람다가 어떤 메서드의 유일한 인수인 경우 메서드의 괄호를 생략할 수 있다.
button.setOnClickListener { v : View? ->
// 클릭 시 처리
}
// 컴파일러가 자료형을 추론하는 경우에는 자료형을 생략할 수 있다.
button.setOnClickListener { v ->
// 클릭 시 처리
}
// v를 _로 대체 가능
button.setOnClickListener { _ ->
// 클릭 시 처리
}
// 람다식에서 인수가 하나인 경우에는 이를 아예 생략하고 람다 블록 내에서 인수를 it으로 접근할 수 있다.
button.setOnClickListener {
// 클릭 시 처리
}
- SAM 변환은 자바에서 작성한 인터페이스일 때만 동작한다!!
'# 02 > 코틀린' 카테고리의 다른 글
[Kotlin] 코드 예제 MainActivity.kt (0) | 2019.07.08 |
---|---|
[Kotlin] 안드로이드 코딩 3 (0) | 2019.07.08 |
[Kotlin] 안드로이드 코딩 1 (0) | 2019.07.07 |
[Kotlin] 코틀린의 다양한 함수들 2 (0) | 2019.07.07 |
[Kotlin] 코틀린의 다양한 함수들 1 (0) | 2019.07.05 |