본문 바로가기

# 02/코틀린

[Kotlin] 안드로이드 코딩 2

반응형

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 변환은 자바에서 작성한 인터페이스일 때만 동작한다!!


반응형