Kotlin 문법 - 연산자
Kotlin에서 제공하는 산술 연산자, 비교 연산자, 논리 연산자, 대입 연산자, 증감 연산자, 비트 연산자, Null 안전 연산자, 타입 검사 및 변환 연산자에 대해서 알아보겠습니다.
산술 연산자
덧셈, 뺄셈, 곱셈, 나눗셈과 같은 기본적인 산술 연산을 위한 연산자입니다. +, -, *, /, %가 산술 연산자에 포함됩니다.
1
2
3
4
5
6
7
8
val a = 10
val b = 5
println(a + b) // 15
println(a - b) // 5
println(a * b) // 50
println(a / b) // 2
println(a % b) // 0
비교 연산자
등호, 부등호 및 크기 등의 비교 연산을 위한 연산자입니다. ==, !=, <, >, <=, >=가 비교 연산자에 포함됩니다.
1
2
3
4
5
6
println(a == b) // false
println(a != b) // true
println(a < b) // false
println(a > b) // true
println(a <= b) // false
println(a >= b) // true
여기서 주의해야할 점이 있습니다. Java의 == 연산자는 객체의 참조값, 즉 메모리 주소를 비교합니다. 따라서 두 변수가 동일한 객체를 가리키고 있는지를 판단하기 때문에 객체의 내용이 같더라도 참조가 다르면 false를 반환하게 됩니다. Java에서는 객체의 내용을 비교하려면 equals() 메소드를 이용해서 비교해야 합니다.
1
2
3
4
String a = new String("abc");
String b = new String("abc");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
반면에, Kotlin의 == 연산자는 객체의 내용을 비교합니다. 즉, Kotlin에서 == 연산자는 Java의 equals() 메소드와 동일하게 작동합니다. 만약 Kotlin에서 참조를 비교하고 싶다면 === 연산자를 사용해야 합니다.
1
2
3
4
5
6
7
8
9
val a = "abc"
val b = "abc"
println(a == b) // true
println(a === b) // true
val c = String("abc".toCharArray())
val d = String("abc".toCharArray())
println(c == d) // true
println(c === d) // false
위 예시에서 a와 b에 “abc”를 별도로 대입했는데 왜
===의 연산자가true일까요?이는 Kotlin과 Java가 문자열 리터럴 처리 시
String Pool이라는 메모리 영역을 사용하기 때문입니다.String Pool은 문자열 리터럴에 대해 한 번만 메모리를 할당하고, 같은 값을 가진 문자열 리터럴에 대해 같은 참조를 반환하는 특징이 있습니다. 이는 메모리 사용량을 줄이는데 도움이 됩니다.
논리 연산자
and, or, not 등의 논리 연산을 위한 연산자입니다. &&, ||, !가 논리 연산자에 포합됩니다.
1
2
3
4
5
6
val a = true
val b = false
println(a && b) // false
println(a || b) // true
println(!a) // false
println(!b) // true
대입 연산자
연산자의 왼쪽에 있는 변수(lvalue)에 연산자의 우측에 있는 값(rvalue)를 대입하는 연산자입니다. =, +=, -=, *=, /=, %=가 대입 연산자에 포함됩니다.
1
2
3
4
5
6
7
8
9
10
11
var a = 5
a += 3
println(a) // 8
a -= 2
println(a) // 6
a *= 4
println(a) // 24
a /= 3
println(a) // 8
a %= 7
println(a) // 1
증감 연산자
변수의 값을 1만큼 증가, 또는 감소 시키는데 사용되는 연산자입니다. ++, --가 증감 연산자에 포함됩니다.
전위 증감 연산자
연산자를 변수 앞에 두어 증감 연산을 먼저 수행하고, 그 결과를 사용합니다.
1
2
3
var num = 10
println(++num) // 11
println(--num) // 10
후위 증감 연산자
연산자를 변수 뒤에 두어 현재 값을 사용한 후 증감 연산을 수행합니다.
1
2
3
4
var num = 10
println(num++) // 10
println(num--) // 11
println(num) // 10
비트 연산자
비트 단위의 연산에 사용되는 연산자입니다. shl, shr, ushr, and, or, xor, inv가 비트 연산자에 포함되어 있습니다. 일반적인 연산자처럼 사용할 수도 있으며 메소드로도 사용이 가능합니다.
shl 왼쪽으로 비트 이동
shr: 오른쪽으로 비트 이동
ushr: 부호를 무시하고 오른쪽으로 비트를 이동
and: 비트 AND 연산
or: 비트 OR 연산
xor: 비트 XOR 연산
inv: 비트 NOT 연산
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val a = 5
println(a.shl(1)) // 10
println(a shl 1) // 10
println(a.shr(1)) // 2
println(a shr 1) // 2
println(a.and(3)) // 1
println(a and 3) // 1
println(a.or(3)) // 7
println(a or 3) // 7
println(a.xor(3)) // 6
println(a xor 3) // 6
println(a.inv()) // -6
val b = -4
println(b ushr 1) // 2147483646
Kotlin의 Infix 함수
infix키워드는 Kotlin에서 특별한 종류의 함수를 정의하는데 사용되며 함수가 두 개의 연산자 사이에서 사용될 수 있음을 나타냅니다. 즉, 함수를 좀 더 자연스러운 방식으로 호출할 수 있도록 해주는 Syntactic Sugar 입니다. 위의 예시에서shl,shr등의 비트 연산자 함수들은infix함수로 선언되어 있습니다.
Null 안전 연산자
Kotlin의 특징인 Null 안전성 제공을 위한 연산자입니다. ?., ?:, !!가 Null 안전 연산자에 포함됩니다.
?.: null이 아닌 경우 연산 수행, null일 경우 null 반환
?:: null이 아닌 경우 연산 수행, null일 경우 오른쪽 값 반환
!!: 값이 null일 경우 NullPointerException 발생, null이 아니라고 확신하는 경우에 사용
1
2
3
4
5
6
7
var a: String? = null
println(a?.length) // null
println(a?.length ?: 0) // 0
a = "abc"
println(a!!.length) // 3
var b: String? = null
println(b!!) // NullPointerException
타입 검사와 변환 연산자
Kotlin에서 타입 종류 확인 및 변환을 위한 연산자입니다. is, as, as?가 이에 포함됩니다.
is: 특정 타입인지 확인하는 연산
as: 타입을 변환하는 연산
as?: 변환 가능한 경우 타입을 변환하고 불가능한 경우 null 반환
1
2
3
4
5
6
val a: Any = "abc"
println(a is String) // true
val b: String = a as String
println(b) // "abc"
val c: Int? = a as? Int
println(c) // null
마무리
Kotlin에 대한 추가적인 정보는 다음 링크를 참고하시면 되겠습니다.
- Kotlin 개요 및 문서와 튜토리얼 등 Kotlin과 관련된 다양한 정보
- Kotlin 기본 문법 및 기능을 배우기 위한 연습 문제 제공
- Google에서 제공하는 Kotlin을 이용한 Android 개발 가이드
