안드 공부를 해볼까?

[Kotlin] 코틀린 함수와 변수 본문

문법/Kotlin

[Kotlin] 코틀린 함수와 변수

문바리 2022. 12. 16. 16:56
728x90

1. 개요

Kotlin IN ACTION 이라는 책을 사용해 코틀린을 공부하고 있습니다.

코틀린을 사용한지 1년이 되는 지금, 내가 모르는 부분이 더 있는지, 더 deep하게 들어가기 위해 정리하고자 합니다.

(사실 스터디 때문에 샀는데 스터디 파토난지 꽤 됐다..)

2. 목차

- 함수

- 변수

3. 본문

1. 함수

먼저 코틀린을 사용하기전에 자바를 사용했던 사람들이 많다고 생각합니다.

그리고 모두다 main 함수에 Hello World를 사용해봤을 겁니다.

public class Solution {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
fun main(args: Array<String>) {
    print("Hello World")
}

그렇다면 자바와 다른 점은 어떤 것이 있을까요?

1. 함수 정의 방법

코틀린에서 함수는 fun으로 사용하고 파라미터의 타입은 변수명 뒤에 씁니다.(변수 : 변수타입)

또한 접근제어자의 default는 public입니다.

 

2. 최상위 함수

코틀린은 자바와 다르게 클래스 외부에서 함수를 만들 수 있습니다. 이를 최상위 함수라고 합니다.

그렇다면 이 최상위 함수는 어떻게 만들어지는 걸까요?

test.kt 파일을 자바로 디컴파일 했을 때 나오는 모습입니다.

파일명 + kt로 클래스가 생성되고 내부에 public(default) static으로 생성됩니다.

즉, 최상위 함수는 어디서나 접근 가능한 함수라고 생각하면 됩니다.

(추가로 자바와 코틀린은 100% 상호작용 가능합니다!)

 

3. 세미콜론

코틀린은 자바와 다르게 세미콜론을 안붙여도 됩니다! 붙여도 무시됩니다.

1-2. return 값이 있는 함수

방금까지는 반환값이 없는 함수를 기준으로 설명했습니다. 하지만 return하는 값이 있는 함수는 어떻게 선언할까요?

fun main(args : Array<String>){
    //12
    print(sum(10, 2))
    //15
    print(sum2(10,2,3))
}

fun sum(a : Int, b : Int) : Int{
    return a + b
}

fun sum2(a : Int, b : Int, c : Int) = a + b + c

자바는 반환하는 자료형을 앞에 적지만 코틀린은 맨 뒤에 적습니다.

또한 바로 return 할 수 있는 함수는 fun 함수이름(파라미터) = return 하는 값으로 대체할 수 있습니다.

이렇게 적을 수 있는 것은 코틀린의 장점 중 하나인 타입추론을 해주기 때문입니다.

2. 변수

코틀린에서는 변수를 변수 변수명 : 변수타입 = 변수에 할당하는 값으로 변수를 만들 수 있습니다.

또한 반드시 초기화를 해줘야 하고 기본적으로 null을 허용하지 않습니다.(변수뒤 ?를 붙여 허용해줄 수는 있습니다.)

2-1. 변경이 불가능한 val(value)

fun main(args: Array<String>) {
    // 변경이 불가능한 val, 뒤에 Int는 생략가능
    val value : Int = 1
    // 1로 이미 선언한 상태, 컴파일 오류가 나옴
    value = 3
    
    val list = mutableListOf<String>()
    list.add("안녕")
    list.add("하세요")
    
    // list 자체가 변경되면 안됨
    list = mutableListOf()
}

자바의 final 변수에 해당하는 변수입니다. 읽을 수는 있지만 변경할 수는 없습니다.

여기서 궁금한 점은 list에 add를 하면 그것도 변경하는 것 아닐까? 라는 생각이 들 것입니다.

 

자바를 기준으로 보면 변수를 선언할때 힙영역스택영역이 존재합니다.

static 같은 값은 스택에 할당되고 단순한 변수는 힙영역에 할당이 되는것이죠.

value = 1라고 하면 힙영역에 1이 할당이 된 상태일 것이고 2로 바꾸면 1이 아닌 2를 가르키게 됩니다.

변수를 바꾸면 가르키는 메모리 주소가 달라지기 때문에 변경이 안되는 것 입니다.

(더 자세하게 해볼려면 hashCode를 사용해서 출력해보세요.)

 

그렇다면 list같은 것은 왜 변하지 않을까요?

list에 add를 한다고 해서 가르키는 메모리 주소가 달라지지 않기 때문입니다.

즉, 객체의 내부 값은 변경이 가능하다는 것 입니다!

하지만 list 자체를 변경시킬려면 메모리가 달라지기 때문에 컴파일 오류가 나오게 되는 것이죠.

 

정리하자면 val은 읽을수만 있고 변하면 안되는 변수형태 입니다.

2-2. 변경이 가능한 var(variable)

fun main(args: Array<String>) {
    //var은 변경 가능
    var num = 1
    num = 3

    //list 또한 변경 가능
    var list = mutableListOf<String>()
    list.add("123")
    
    list = mutableListOf()
}

자바의 일반 변수에 해당하는 형태입니다.

변경이 가능하지만 반드시 변수 타입에 맞춰서 변경을 해줘야 합니다.

num은 현재 1, Int인 상태고 Int변수라면 모든 값이 들어갈 수 있습니다.

2-3. 그렇다면 언제 val을 쓰고 var을 쓸까?

사실 아직도 헷갈리는 부분입니다. 같은 변수면서 왜 변경가능한 것과 하지 않는것을 구분했을까요?

 

제 생각은 코드 가독성 + 개발 의도라고 생각합니다.

변할 수 있는 변수와 없는 변수를 나누어 어떤 개발 흐름인지 볼 수 있다고 생각했습니다.

또한 "이것 바뀌면 안되는 변수다."라고 명시적으로 알려줄 수 있는 방법도 있을겁니다.

3. 결론

이번 포스팅에서는 함수와 변수가 자바에 비해서 어떤 것이 달라진건지, 어떻게 사용해야하는지 간단하게 보았습니다.

함수는 fun으로 선언하고 변수는 val, var로 선언합니다.

val는 변하면 안되는 변수, var은 변해도 상관없는 변수고 val 같은 경우는 클래스의 프로퍼티는 변경 가능합니다.

반응형
Comments