Kotlin 으로 업무도 많이 했지만,
Android 개발을 Java 로 시작해서 Kotlin 으로 점차 넘어갈 때는 제대로 공부를 못하고 바로 업무를 하게 되었다.
Java 를 쓰다 Kotlin 으로 넘어오면, 비슷한 부분이 많아 크게 어려운 부분은 없고
검색해보면 금방 처리 할 수는 있었다.
하지만 기본적인 것을 건너뛰고 바로 업무에 사용하다보니
모르고 사용하던 것들도 많고, 효율적이지 못한 코드도 많이 사용해온 것 같다.
Java 에 비해 간결하게 짤 수 있는 코드도, 기본기가 없었던 내겐 단지 동작에 문제가 없으면 만족할 뿐이었다.
서론이 길었지만, 이제라도 기본기를 다듬고 싶어서 천천히, 너무나 쉬운 내용부터 정리를 해본다.
변수 선언 : val 과 var
// val = value -> immutable
val a: Int = 0
a = 1 // X : 컴파일 에러 발생.
// var = variable -> mutable
var b: Int = 0
b = 1 // O
String template :
Java 에서는 string 데이터와 변수를 같이 사용할 때, + 를 이용했지만 Kotlin 에는 String template 라는 것이 있다.
//1. 단일 변수에 대해서는 아래와 같이 사용하면 된다.
val name = "1minute"
println("my blog name is $name")
//2. 꼭 변수 뿐 아니라, 중괄호를 이용해 아래와 같이 사용할 수 있다.
println("1 + 2 는 ${1 + 2} 이야")
//3. 변수, 연산, 함수의 반환값 등을 중괄호에 감싸서 사용할 수 있다.
//4. 실제 $를 문자로 사용하고 싶다면, 짐작가겠지만 backslash("\")를 앞에 붙여주면 된다.
println("나는 문자열 \$를 사용할 거야.")
조건문
이미 다른 개발 언어를 사용하던 사람이라면, 비슷한 방식으로 사용할테니 어려움은 없을 것이다.
때문에 Java 기준으로 조금 다른 부분만 정리한다.
- if
// kotlin 에는 삼항 연산자가 없지만, 비슷한 방법으로 사용할 수 있다
fun compare(a: Int, b: Int) = if(a < b) b else a
/**
* kotlin을 많이 사용해보지 않은 사람이 봤을 땐,
* 함수 치고는 의아할 수 있는 한 줄이기에 추가로 설명을 남겨본다.
*
* 우선, kotlin 에서는 함수 반환형을 함수명 뒤에 콜론(:)을 붙여 작성한다.
*/
// 예시
fun getString(): String {
return "string"
}
// 반환형을 생략하면 java 의 void 와 같지만
fun setString(str: String) {
this.str = str
}
// 실제로는 반환형 Unit 이 생략된 것으로, 굳이 따지면 void 와 조금 다르다.
fun setString(str: String): Unit {
this.str = str
}
/**
* 이제 다시 맨 위 예시 코드를 보면 이렇게 설명할 수 있겠다.
*
* 자동 타입 추론으로 인해 반환형도 생략되었고,
* return 또한 사용하지 않고 아래와 같은 방식으로 간결하게 사용이 가능하다.
*/
fun compare(a: Int, b: Int) = if(a < b) b else a
- when : switch 와 비슷
// 평범하게 사용해보면, 아래와 같이 사용할 수 있다.
fun getResult(score: Int): String {
when(score) {
0 -> return "babo"
100 -> return "genius"
else -> return "normal"
}
}
// 위의 함수는 해당 값에 일치할 경우이지만, 아래와 같이 범위를 지정할 수도 있다.
fun getResult(score: Int): String {
when(score) {
in 0..50 -> return "babo"
in 90..100 -> return "genius"
else -> return "normal"
}
}
// 가독성을 위해 위와 같이 사용했지만, 마찬가지로 아래와 같이 간결하게 작성할 수도 있다.
fun getResult(score: Int) = when(score) {
in 0..50 -> "babo"
in 90..100 -> "genius"
else -> "normal"
}
Expression 과 Statement
이해하고 있는 내용으로는 아래와 같이 설명할 수 있다.
/**
* [Expression]
* 아래 코드의 grade 변수는 non-null 변수이기 때문에 else 가 존재해야만 한다.
* 그렇지 않다면, 컴파일 오류가 발생할 것이다.
* (non-null 에 대해서는 아래에서 설명할 예정이다.)
**/
val grade = when(score) {
in 0..50 -> "babo"
in 90..100 -> "genius"
else -> "normal"
}
/**
* [Statement]
* 하지만 아래 코드처럼 어딘가에 결과물을 담거나 하지않고,
* 단지 분기에 따라 출력만 한다면 else 가 없어도 문제가 없다.
**/
when(score) {
in 0..50 -> println("you are babo")
in 90..100 -> println("you are genius")
}
결과적으로 Kotlin의 모든 함수는 Expression 이라고 한다.
이유는 Java 의 반환형 void 는 반환되는 값이 없지만,
Kotiln은 반환형 생략 시 위에 말한대로 Unit을 반환하기 때문이다.
Java에서는 조건문을 Statement 로 밖에 사용을 못했지만,
Kotlin에서는 Expression 으로도 사용할 수 있는 차이가 있다.
반복문
- for
// 1 부터 10 까지 1씩 증가
for(i in 1..10) {
println(i)
}
// 1 부터 10 까지 2씩 증가
for(i in 1..10 step 2) {
println(i)
}
// 10 부터 1 까지 1씩 감소
for(i in 10 downTo 1){
println(i)
}
// 10 부터 1 까지 2씩 감소
for(i in 10 downTo 1 step 2){
println(i)
}
/**
* 1 부터 10까지 1씩 증가하지만, 10을 포함하지 않는다
* Java 기준으로는 보통 array 나 list 로 반복문을 사용할 때
* 조건을 size - 1 과 같은 식으로 입력해주어야 할 때 until 을 이용하면 된다.
**/
for(i in 1 until 10) {
println(i)
}
/**
* 만약 과일 이름들이 담긴 list 변수 "fruits" 가 있다고 할 때,
* 아래와 같이 withIndex() 를 이용하면 index 값도 얻어와 사용할 수 있다.
**/
for(fruit in fruits.withIndex()) {
println("index : ${fruit.index}, value : ${fruit.value}")
}
Non-Null
Java 와 차이가 있는 부분 중 하나이다.
Java 의 경우 값이 null 인데, 사용하려는 경우 Runtime 오류로 NullPointerException 이 발생할 수 있다.
하지만, Kotlin 에서는 Runtime 시점이 아닌 Compile 시점에도 오류 확인이 가능하다.
변수 선언 시, 기본적으로는 Non-Null 방식이기 때문이다.
// 기본적으로 변수를 선언하면, non-null 방식으로 변수에 null 값이 들어갈 수 없다.
var blog: String = "1Minute"
// Null이 들어갈 수 있게 변수 선언을 하려면, 아래와 같이 ? 를 사용하면 된다.
var blog: String? = null
null 을 넣을 수 있는 Nullable 방식으로 변수를 선언했을 때,
해당 변수를 사용하려 할 때, null 일 수 있는 상황에서는 error 가 표시된다.
사용할 때 null check 를 해주어야만 한다.
방법은 아래와 같이 여러가지가 있다.
- "?" 를 이용하는 방법
아래와 같이 Nullable 방식으로 스트링 변수를 선언 후
단순히 length 를 가져오려고만 해도 error 표시가 뜨는 것을 볼 수 있다.
var testString: String? = "test"
var length = testString?.length
이 때, 변수 뒤에 ? 를 붙여주면
testString이 null 이 아니면, 정상적으로 length를 반환하고
testString이 null 이면, null을 반환한다.
Java 와 달리 "?" 하나로 간결하게 null 체크가 가능하다.
- "?:" 를 이용하는 방법
엘비스 연산자라고 표현하는데, null 인 경우 default 값을 설정해주는 것이다.
var testString: String? = null
var length = (testString?:"test").length
Nullable 방식으로 선언된 testString 값이 null 이기 때문에 위와 같이 사용할 경우,
default 값을 "test"로 지정했기 때문에 length 값은 4로 설정된다.
- "!!" 를 이용하는 방법
많이 사용하는 것은 좋지 않다. (나는 엄청 썼다.)
"null 이 아니다" 라고 직접 설정해주는 것이다.
var testString: String? = "test"
var length = testString!!.length
개발을 하다보면 정말로 해당 변수는 null 이 될 수 없는 상황이 있을 수 있다.
그 때만 사용한다면 문제가 없을 것이다.
(남발할 경우에는 NullPointerException 이 발생할 수 있다.)
- "let" 을 이용하는 방법
null 이 아닐 경우, let 람다식 안의 내용이 실행된다.
var testString: String? = "test"
testString?.let {
println(it)
}
it 로 받아서 사용할 수 있다.
null 인 경우, let 블록 내의 내용이 실행되지 않기 때문에 안전하다고 볼 수 있다.
이렇게 기본적인 문법을 알아보았지만,
제목에서부터 알 수 있듯이 기본 문법에 대하여 추가로 정리를 할 예정이다.
'Development' 카테고리의 다른 글
[Android] Doze 모드 테스트 하기 (0) | 2020.11.09 |
---|---|
[코딩테스트 연습] 같은 숫자는 싫어 (0) | 2020.04.06 |
[코딩테스트 연습] 크레인 인형뽑기 게임 (0) | 2020.04.03 |