Kotlin

[Kotlin] 코틀린 기초 - 변수와 타입, 스코프 함수

코냥이 2024. 6. 6. 22:53

 

들어가기

Java로 개발 중인 스터디 프로젝트에서 Kotlin을 적용하기로 했다.

항상 Java만 사용했었는데, 새로운 언어를 경험할 수 있게 되어서 굉장히 기대가 된다!

Kotlin의 기초 중 하나인 변수와 타입, 그리고 스코프 함수에 대해 알아보자!

 

 

 

 

✔️ Kotlin 변수


변수 선언 기본 형태

코틀린 변수 선언 형태

 

키워드(Keyword)

코틀린은 변수 선언 시, 해당 변수의 변경 가능 여부를 나타내는 키워드(Keyword)를 필수로 붙여주어야 한다.

키워드에는 val과 var이 있다.

  • val (value)
    • 변경 불가능한(immutable) 변수로 지정하는 키워드이다.
    • Java의 final 키워드와 동일하다.
  • var (variable)
    • 변경 가능한(mutable) 변수로 지정하는 키워드이다.
    • Java의 일반적인 변수와 동일하다.

 

 

변수 타입 명시

코틀린은 변수명: 변수 타입 의 형태로 변수 타입을 명시한다.

 

변수 타입은 생략 가능하다.

타입을 생략했을 경우, 컴파일러가 초기화 식을 분석하여 변수의 타입을 지정한다. 이를 타입 추론(Type Inference)이라고 한다.

val a:Int = 5
val b = "kotlin" // String으로 타입 추론
val c = 12L // Long으로 타입 추론

 

 

 

 

 

✔️ Kotlin 타입


코틀린은 자바와 다르게, 원시 타입(Primitive Type)과 참조 타입(Reference Type)을 구분하지 않는다.

 

정수 자료형

Type Size (bits)
Byte 8
Short 16
Int 32
Long 64

 

실수 자료형

Type Size (bits)
Float 32
Double 64

 

논리 자료형

Type Value
Boolean true / false

 

문자 자료형

Type Description
char 작은 따옴표(')로 값을 감싸서 표현한다.

 

문자열 자료형

Type Description
String 큰 따옴표(")로 값을 감싸서 표현한다.

 

 

 

 

✔️ Kotlin 스코프 함수(Scope Function)


코틀린은 스코프 함수(Scope Function)가 제공된다.

 

스코프 함수(Scope Function)는 객체 생성 시 사용되는 함수로, 특정 객체가 다루는 범위를 생성해서 프로퍼티 혹은 메소드를 처리하는 코드를 간결하게 만들거나, 메소드 체이닝에 활용하는 함수이다.

람다(lambda) 표현식을 사용하여 스코프 함수를 호출하면 임시적으로 스코프가 설정된다.

람다(lambda) 표현식
: 메소드를 하나의 식으로 표현한 것으로, 이름이 없는 메소드이다.

 

 

스코프 함수에는 총 5가지가 존재한다. 각각의 함수는 서로 2가지 차이점이 존재한다.

  1. 해당 객체를 코드 블록 안에서 사용 가능하게 만드는 방법 (it vs this)
  2. 전체 표현식의 결과 (Lambda Resut vs Context Object)

 

Function Object Reference Return Value Is Extension Function
apply it Lambda Result Yes
run this Lambda Result Yes
with this Lambda Result No
also this Context Object Yes
let it Context Object Yes

 

 

 

(1) apply

data class Student(val name: String, var number: Int)

val student = Student("Hong").apply{
	number = 15
}
  • 주로 객체를 새로 생성하고 특정 변수에 할당하기 전에 초기화 작업을 하는 용도로 사용한다.
  • apply 함수의 명령들이 모두 수행된 후에 새로 생성된 객체를 반환한다.
  • 반환 결과가 객체 자신이다.
  • 확장 함수이기 때문에 객체 컨텍스트를 reciever(this) 로 사용 가능하다.

 

 

(2) run

data class Student(val name: String, var number: Int)

val student = Student("Hong", 15)
val nextNumber = student.run {
	++student
}
  • 주로 특정 객체의 속성을 출력하거나 계산 값으로 활용하는 등 핸들링할 때 사용된다.
  • apply와 다르게, 반환 값이 객체가 아닌 스코프에서 실행된 값이다.
  • 확장 함수이기 때문에 객체 컨텍스트를 reciever(this) 로 사용 가능하다.
  • safe call(.?)을 붙여서 non-null 일 때만 실행 가능하도록 할 수 있다.

 

 

(3) with

data class Student(val name: String, var number: Int)

val student = Student("Hong", 15)

with(student) {
    println("Student name : $name")
    println("Student Number : $number")
}
  • 반환 값이 객체가 아닌 스코프에서 실행된 값이다.
  • 확장 함수가 아니기 때문에, 객체 컨텍스트를 argument로 전달한다.
  • 객체를 argument로 받기 때문에 이미 생성된 객체에 여러작업을 일괄적으로 해야할 때 유용하다.
  • 람다의 내부에서는 확장 함수로 적용돠어 reciever(this) 로 사용 가능하다.

 

 

(4) also

class StudentCheck(student: Student) {
    val student = student.also {
        requireNotNull(it.number)
        println(it.name)
    }
}
  • 객체의 프로퍼티를 전혀 사용하지 않거나, 변경하지 않고 사용하는 경우에 유용하다.
    • Ex. 객체 데이터의 유효성 확인, 디버깅, 로깅 등의 부가적인 목적
  • apply 함수와 동일하게 반환 결과가 객체 자신이다.
  • it을 사용해서 프로퍼티에 접근 가능하다.

 

 

(5) let

getStudent()?.let {
    println(it)     // it: student, null이 아닐 때만 실행된다.
}
  • 주로 해당 객체가 Null이 아닐 때 코드 블럭을 실행하고, Null일 때 실행하지 않도록 구현할 때 사용한다.
  • 반환 값이 객체가 아닌 스코프에서 실행된 값이다.
  • it을 사용해서 프로퍼티에 접근 가능하다.

 

 

 

 

 

 

 

 

출처

 

 

 

긴 글 읽어주셔서 감사합니다 🍀

잘못 작성된 내용은 피드백 주시면 반영하겠습니다 😎