[코틀린] 타입 선언과 연산자

0

about KOTLIN

목록 보기
1/3
post-thumbnail

타입 선언 방법(타입 애노테이션, 타입 추론)

코틀린에서 변수의 자료형을 선언하는 방법에는 타입 애노테이션과 타입 추론이 있습니다.

타입 애노테이션

일반적으로 타입 애노테이션은 변수 이름 다음에 콜론(:)을 붙여 선언합니다.
다음 코드에서는 userName 변수를 String타입으로 선언하고 초기화 합니다.

val userName: String = "Jin"

타입 추론

그렇다면, 다음 코드와 같이 타입 애노테이션 없이 변수를 초기화하면 어떻게 될까요?

val userName = "Kazuya"

위 코드도 결과적으로 String 타입의 userName 변수가 초기화되어 선언됩니다.

코틀린에서는 컴파일러가 초기화되는 값의 타입을 변수의 타입으로 간주하여 선언해주는 타입 추론 기능이 있습니다.

val pi = 3.141592 // Type inferred : Double
val firstName = "Lee" // Type inferred : String

위와 같이, 일반적으로 부동 소수점 수인 pi는 Double 타입으로 선언되고, 문자열 형태인 firstName은 String으로 선언됩니다.

null 가능 타입(Nullable)

코틀린에서는 null 값을 가지는 변수에 대해 발생하는 NPE(NullPointerException)에러를 방지하기 위해, null 값을 지정할 수 있는 null 가능 타입을 선언할 수 있습니다. null 가능 타입은 타입 애노테이션 뒤에 물음표(?)를 붙여 선언합니다.

// without Nullable Type
val weight: Int = null
println(weight) // Kotlin: Null can not be a value of a non-null type Int

// with Nullable Type
val weight: Int? = null
print(weight) // output: null

연산자(Safe call, Not-Null assertion, Elvis operator)

안전 호출 연산자(safe-call)

앞서 null 가능 타입은 불필요한 null 포인터 예외를 막기 위해서 사용한다고 언급했었습니다.
만약 다음 코드와 같이 nullable 변수를 split 함수를 통해 새로운 배열을 만들려고 한다면 어떻게 될까요?

val name: String? = "Mishima heihachi"
val split = name.split(" ")

이렇게 코드를 작성한다면 다음과 같은 에러가 발생합니다.

Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?

저희는 위 코드에서 "Mishima heihachi"라고 정확한 String 값을 지정해 주었지만, 컴파일러 입장은 조금 다릅니다.
컴파일러 입장에서는 정확한 값이 선언되더라도 null 값이 나올 수 있다는 불안감(?)이 찾아오게 되죠.

따라서, name null이 아닐때만 split 함수 호출이 가능하도록 컴파일러를 안심시켜야합니다. 다음과 같은 코드로 말이죠.

if (name != null) {
	val split = name.split(" ")
}

물론 이렇게 코드를 작성해도 되지만, 훨씬 효율적인 방법이 있습니다. 다음과 같이 안전 호출 연산자(?.)를 사용하는 것입니다.

val split = name?.split(" ")

위 코드로 보다 간결하게 컴파일러를 안심시킬 수 있습니다.
이 경우에도 name이 null이 아닐 경우에만 split() 함수가 호출되어 split에 저장할 수 있도록 합니다.

Not-null 단정자(Not-null assertion)

안전 호출 연산자의외에도 컴파일러를 안심시킬 수 있는 방법은 Not-null 단정자를 사용하는 것입니다. 이는 컴파일러에게 이 변수는 null이 무조건 나오지 않는다고 알려주는 연산자입니다. Not-null 단정자는 변수명 끝에 느낌표 두개(!!)로 나타냅니다.

val name: String? = "Lee"
val len = name!!.length

이 코드를 작성하면 컴파일러는 Null이 안나오는 변수인 변수라고 인지하고 해당 코드를 통과시키게 됩니다.

그러나 Not-null 단정자를 써놓고 변수의 값이 null이라면 런타임단에서 NPE에러가 발생하므로 주의해야 합니다.

val name: String? = null
val len = name!!.length

<Console>
Exception in thread "main" java.lang.NullPointerException
	at MainKt.main(Main.kt:3)

엘비스 연산자(Elvis operator)

null 가능 타입으로 변수를 지정하고, 만약 null 값에 대한 예외 처리를 하고 싶다면 엘비스 연산자를 사용하시면 됩니다.
엘비스 연산자는 물음표와 콜론을 붙인형태(?:)로 사용합니다.

val name: String? = "Lee"
println(name ?: "null 입니다."

<Console>
Lee

이 코드는 만약 왼쪽 항에 있는 name 값이 null 이라면 오른쪽 항에 있는 내용을 출력하고, null이 아니라면 name을 출력합니다.
따라서 엘비스 연산자는 다음과 같은 코드와 같은 의미를 지니고 있습니다.

if (name == null) {
	println("null 입니다.")
} else {
	println(name)
}

0개의 댓글