본문 바로가기
Program Language/Kotlin

[Do it! 코틀린 프로그래밍] 2. 변수와 자료형, 연산자

by SungJe 2021. 3. 30.

2. 변수와 자료형, 연산자


1. 코틀린 패키지

코틀린 프로젝트(Project)는 모듈(Module), 패키지(Package), 파일(File) 로 구성된다. 프로젝트에서 하나의 기능은 하나의 모듈 단위로 분리하여 관리한다. 서로 다른 패키지에 존재하는 파일(클래스)는 이름이 중복되어도 오류가 발생하지 않는다.

Kotlin Project

NOTE✏️
코틀린에서 파일은 하나의 클래스만 정의된 경우 .kt 확장자를 생략한 클래스 이름만 표시된다. 즉, 파일 이름과 클래스의 선언 개수에 큰 의미를 두지 않는다.

코틀린 기본 패키지: 코틀린에서 자주 사용하는 클래스와 함수 등을 미리 만들어 놓은 것으로 import 키워드로 선언하지 않아도 바로 사용 가능

  • kotlin.* : Any, Int, Double 등 핵심 함수와 자료형
  • kotlin.text.* : 문자와 관련된 API
  • kotlin.sequences.* : 컬렉션 자료형의 하나로 반복이 허용되는 개체를 열거
  • kotlin.ranges.* : if문이나 for문에서 사용할 범위 관련 요소
  • kotlin.io.* : 입출력 관련 API
  • kotlin.collections.* : List, Set, Map 등의 컬랙션
  • kotlin.annotation.* : 애노테이션 관련 API

2. 변수와 자료형

  • 변수
    코틀린에서 변수는 valvar라는 키워드를 이용하여 선언할 수 있다. val로 변수를 선언하면 초기 값을 지정하면 더 이상 바꿀 수 없는 읽기 전용 변수가 된다. var로 변수를 선언하면 언제든지 값을 바꿀 수 있다. 그리고 코틀린은 선언과 동시에 값을 할당하면 자료형을 추론한다.
  • 변수 선언 예시
val username: String = "Kim" // String 자료형으로 명시
val age = 25 // Int 자료형으로 추론
val address // 자료형을 지정하지 않아 오류발생
  • 변수 명명 규칙
    변수 명명 규칙에 대해서는 공식 사이트를 참고한다. Link

  • 자료형
    코틀린은 참조형 자료형을 사용한다. 참조형 자료형은 코틀린 컴파일러가 자동으로 최적화를 수행한다.

    • 정수 자료형: 자료형을 명시하지 않으면 Int 자료형으로 추론된다.

      형식 자료형 크기
      정수 자료형 Long 8 Byte(64 bit)
      Int 4 Byte(32 bit)
      Short 2 Byte(16 bit)
      Byte 1 Byte(8 bit)
      부호 없는
      정수 자료형
      ULong 8 Byte(64 bit)
      UInt 4 Byte(32 bit)
      UShort 2 Byte(16 bit)
      UByte 1 Byte(8 bit)
    • 실수 자료형: 자료형을 명시하지 않으면 Double 자료형으로 추론된다. 실수 자료형은 근사값이기 때문에 오차가 발생한다.

      형식 자료형 크기
      실수 자료형 Double 8 Byte(64 bit)
      Float 4 Byte(32 bit)
    • 논리 자료형: 참(true)과 거짓(false)을 표현하는 자료형

      형식 자료형 크기
      논리 자료형 Boolean 1 bit
    • 문자 자료형: 문자를 표현하기 위해 사용하는 자료형

      형식 자료형 크기
      문자 자료형 Char 2 Byte(16 bit)
    • 문자열 자료형(String): 여러 문자를 배열하여 저장할 수 있는 자료형, 기본형에 속하지 않는다.

      • 힙 영역의 String Pool이라는 공간에 문자열을 저장하고 주소를 참조하는 방식으로 메모리 공간을 재활용
      • 문자열 안에 $ 기호를 이용해 변수 값을 사용 가능
      • 문자열 안에 $ 기호와 중괄호({})를 이용하여 표현식을 사용 가능
      • """ 기호를 이용해 형식화된 다중 문자열을 사용 가능
val str1: String = "Hello"
val str2 = "Kotlin"
val str3 = "Hello"

println(str1 === str2) // false
println(str1 === str3) // true

NOTE✏️

  • 기본형 자료형(Primitive Type): 가공되지 않은 순수한 자료형, 자바에서 int, long, float, double 등
  • 참조형 자료형(Reference Type): 객체를 생성하고 동적 메모리 영역에 할당하여 참조하는 자료형, 자바에서 String, Date 등
  • 자릿값 구분: 변수에 값을 할당할 때 읽기 쉽게 하가위해 언더스코어(_)를 사용
val number = 1_000_000_000 // number = 1000000000
  • 부동 소수점(Floating-Point): 유효숫자를 나타내는 가수와 소수점의 위치를 풀이하는 지수로 나누어 표현한다.

3. 자료형 검사하고 변환하기

  • null을 허용한 변수 검사
    코틀린은 변수를 사용할 때 반드시 값이 할당되어 있어야 한다는 원칙이 있다. 만약 null(값이 없는 상태)을 허용하기 위해 물음표(?) 기호를 사용해 선언한다. null을 허용할 경우 null을 검사하고 처리하는 방법까지 고려해야 한다.

    • Safe calls: null이 할당되어 있을 가능성이 있는 변수를 검사하여 안전하게 호출
    • not-null 연산자: 변수에 할당된 값이 null이 아님을 단정하여 컴파일러가 null 검사를 생략, NPE가 발생 가능
    • Elvis 연산자: 변수가 null인지 아닌지 검사하여 null이면 왼쪽 식을 실행하고 null이면 오른쪽 식을 실행
var string: String? = "Hello Kotlin"
string = null

println("General Call: ${string.length}") // 컴파일 오류
println("Safe Call: ${string?.length}") // Safe Call: null
println("not-null: ${string!!.length}") // NPE 발생
println("Elvis: ${string?.length ?: -1}") // Elvis: -1
  • 자료형 변환
    코틀린은 자료형이 다르면 변환 함수를 사용해야 한다.

    • 자동 형 변환: 표현식에서 범위가 큰 자료형으로 자동 형 변환하여 연산
    • 변환 메서드 종류
    매서드 자료형 매서드 자료형
    toLong() Long toFloat Float
    toInt() Int toDouble Double
    toShort() Short toChar Char
    toByte() Byte toString String
val intValue: Int = 1
val doubleValue: Double = a.toDouble() // 변환 메서드 사용
val result = 1L + 3 // 자동 형 변환 (Long형 + Int형 = Long형)
  • 스마트 캐스트: 코틀린 컴파일러가 자동으로 형 변환을 한다.
var number: Number = 12.2 // Double형으로 스마트 캐스트
number = 1 // Int형으로 스마트 캐스트
number = 12L // Long형으로 스마트 캐스트
number = 12.0f // Float형으로 스마트 캐스트
  • 자료형 검사: is 키워드를 사용하여 자료형을 검사한다. 검사한 자료형으로 스마트 캐스트
fun typeCheck(e: Any) {
    when(e) {
        is Int -> println("${e.javaClass} Type") // Int형으로 스마트 캐스트
        is String -> println("${e.javaClass} Type") // String형으로 스마트 캐스트
        else -> println("Other Type")
    }
}
  • as 캐스팅 연산자: 형 변환이 가능하지 않으면 예외가 발생한다. Safe call을 통해 안전하게 캐스팅한다.
val x: Int = y as Int // y가 null이면 예외 발생
val x: Int? = y as? Int ?: -1 // y가 null이면 x에 -1을 대입을 대입

4. 코틀린 연산자

  • 기본 연산자

    • 산술 연산자
    연산자 의미 사용 예
    + 덧셈 3 + 2
    - 뺄셈 3 - 2
    * 곱셈 3 * 2
    / 나눗셈 3 / 2
    % 나머지(Modulus) 3 % 2
    • 대입 연산자
    연산자 의미 사용 예
    = 오른쪽의 표현식을 왼쪽 항에 대입 num = 2
    += 오른쪽의 표현식의 결과를 왼쪽 항에 더한 후 대입 num += 2
    -= 오른쪽의 표현식의 결과를 왼쪽 항에 뺀 후 대입 num -= 2
    *= 오른쪽의 표현식의 결과를 왼쪽 항에 곱한 후 대입 num *= 2
    /= 오른쪽의 표현식의 결과를 왼쪽 항에 나눈 후 대입 num /= 2
    %= 왼쪽 항을 오른쪽의 표현식의 결과로 나머지 연산 후 대입 num %= 2
    • 증감 연산자
    연산자 의미 사용 예
    ++ 항의 값에 1증가 ++num 또는 num++
    -- 항의 값에 1감소 --num 또는 num--
    • 비교 연산자
    연산자 의미 사용 예
    > 왼쪽이 크면 true, 작으면 false num > 2
    < 왼쪽이 작으면 true, 크면 false num < 2
    >= 왼쪽이 크거나 같으면 true, 아니면 false num >= 2
    <= 왼쪽이 작거나 같으면 true, 아니면 false num <= 2
    == 두 항의 값이 같으면 true, 아니면 false num1 == num2
    != 두 항의 값이 다르면 true, 아니면 false num1 != num2
    === 두 항의 참조 주소가 같으면 true, 아니면 false num1 === num2
    !== 두 항의 참조 주소가 다르면 true, 아니면 false num1 !== num2
    • 논리 연산자
    연산자 의미 사용 예
    && 논리곱, 두 항이 모두 참일 때 ture, 아니면 false exp1 && exp2
    || 논리합, 한 항이 참일 때 ture, 모두 거짓이면 false exp1 && exp2
    ! 부정, ture를 false로, false를 true로 바꿈 !exp
  • 비트 연산자

    • 비트 메서드: 중위 표현(Infix-notation)이 가능하다. Link
    사용 예 설명
    4.shl(bits) 4를 bits만큼 왼쪽으로 쉬프트(부호 비트 미포함)
    7.shr(bits) 7을 bits만큼 오른쪽으로 쉬프트(부호 비트 미포함)
    12.ushr(bits) 12를 bits만큼 오른쪽으로 쉬프트(부호 비트 포함)
    9.and(bits) 9를 bits와 논리곱 연산
    4.or(bits) 4를 bits와 논리합 연산
    24.xor(bits) 24를 bits와 배타적 연산
    78.inv() 78을 비트 반전
val bits = 2
println("shl: ${4.shl(bits)}") // shl: 16 
println("shr: ${7.shr(bits)}") // shr: 1
println("ushr: ${12.ushr(bits)}") // ushr: 3
println("and: ${9 and bits}") // and: 0
println("or: ${4 or bits}") // or: 6
println("xor: ${24 xor bits}") // xor: 26
println("inv: ${78.inv()}") // inv: -79