[코틀린의 고급 문법 1]
특별한 상태 값 null
코틀린에서는, 모든 객체는 생성과 동시에 값을 갖도록 초기화 하는 것을 원칙으로 하며
null 사용을 허용하지 않습니다.
즉,
val a: String // 불허
val a: String = null // 불허
하지만, null을 꼭 사용하겠다면, ?를 사용해서 null을 허용하겠다고 명백히 해줘야 합니다.
val a: String? = null
주의) 위 변수 a 사용시 고려할 점
val b: String? = a // 허용 (a나 b나 동류이므로)
val c: String = a // Error (a는 부정확한 상태므로 불허)
val c: String = a!! // a값이 null이 아님을 보증한다는 의미로 !!를 붙여쓰면 허용
늦은 초기화
가끔 초기화를 일부러 늦춰야 하는 경우에 사용합니다. 코틀린에서는 두 개의 키워드로 이를 지원합니다.
(앱이 시작될 때 일부 변수들을 늦게 초기화함으로써 연산을 분산시켜 실행 속도를 빠르게 하기도 함)
lateinit
var 타입의 늦은 초기화 (int, long, float, double과 같은 프리미티브 자료형에는 사용 불가)
lateinit var a : String // 허용
by lazy
val 타입의 늦은 초기화 (프리미티브 자료형에도 사용 가능)
val a : String by lazy {
"Hello"
}
실습)
val str : String by lazy {
println("늦은 초기화!")
"Hello"
}
println(str) // 늦은 초기화!, Hello (str 첫 사용시에만 '늦은 초기화!'가 출력됨)
// (즉, lazy { } 블럭 내부 코드가 한 번만 실행됨)
println(str) // Hello
안전한 호출
.연산자 대신 ?. 연산자를 사용하면 변수 값이 null이 아닌 경우에만 메소드가 호출됩니다 (편리한 기능이네요!)
var nameUpperCase = if (str != null) str else null // 이런 문장을
var nameUpperCase = str?.toUpperCase // 로 간략하게 쓸 수 있다.
또 한 가지 편리한 기능이 있는데, 위에서 str이 null 일 때 nameUpperCase도 null 이 됩니다.
그런데 이 때 엘비스 연산자 ?: 를 사용하면 null 을 대체할 문자열을 대입할 수 있습니다.
var nameUpperCase = str?.toUpperCase ?: "초기화가 안됐어요" // str이 null인 경우 문자열이 대입됨
컬렉션
데이터 집합을 만드는 자료 구조를 말합니다. (예: 리스트, 맵, ...)
원소들의 내용을 수정할 수 없는 타입과 수정할 수 있는 가변형(mutable) 타입이 있습니다.
<리스트>
원소 변경 불가
val colors1: List = listOf("초록", "주황", "빨강", "파랑", "하양")
val colors1 = listOf("초록", "주황", "빨강", "파랑", "하양") // 물론 데이터 형을 생략할 수도 있습니다
원소 변경 가능
val colors2: MutableList = mustableListOf("초록", "주황", "빨강", "파랑", "하양")
val colors2 = mustableListOf("초록", "주황", "빨강", "파랑", "하양")
<colors2.add("검정") // 원소 추가
colors2.removeAt(4) // 원소 제거
color2[0] = "연두" // 원소 변경
<맵>
키-값 쌍의 데이터 집합 (중복불가)
원소 변경 불가
val colors3: Map<String, Int> = mapOf("A" to 90, "B" to 80, "C" to 70, "D" to 60)
val colors3 = mapOf("A" to 90, "B" to 80, "C" to 70, "D" to 60)
println(colors3["B"])
원소 키 값 변경 가능
val colors3: MutableMap<String, Int> = mutableMapOf("A" to 90, "B" to 80, "C" to 70, "D" to 60)
val colors3 = mutableMapOf("A" to 90, "B" to 80, "C" to 70, "D" to 60)
사용 예)
for ((k, v) in colors3) {
println("$k --- $v")
}
<집합>
원소 변경 불가
val cities: Set = setOf("Seoul", "Incheon", "CheongJu")
val cities = setOf("Seoul", "Incheon", "CheongJu")
원소 변경 가능
val cities: MutableSet = mutableSetOf("Seoul", "Incheon", "CheongJu")
val cities = mutableSetOf("Seoul", "Incheon", "CheongJu")
사용 예)
cities.add("Sokcho")
cities.remove("Incheon")
(계속...)