관리 메뉴

나만을 위한 블로그

[Kotlin] 확장 함수(Extension Functions)란? 본문

개인 공부/Kotlin

[Kotlin] 확장 함수(Extension Functions)란?

참깨빵위에참깨빵 2020. 11. 1. 21:11
728x90
반응형

확장 : 범위, 규모, 세력 따위를 늘려서 넓힘

함수 : 코드들의 모음. fun으로 선언하는 그것(본인의 추측임)

 

-> 확장 함수? 범위나 규모 따위가 늘어난 함수? 함수의 범위나 규모를 늘려서 선언하는 것?

 

확장 함수라는 말을 처음 보고 생각한 것들을 간단하게 적어봤다.

공부해보니 코틀린에서 말하는 확장 함수(Extension Functions)란 이미 존재하는 클래스에 함수(메서드)를 추가하는 것이라고 한다.

클래스에 '원래 없었던' 함수를 추가해 클래스의 크기를 넓힌다고도 생각할 수 있으니, 확장이란 단어를 쓴 것이 이해가 된다.

 

그럼 이 확장 함수란 건 어떻게 쓰는 걸까? 간단하게 예시 상황을 만들어보기로 했다.

내가 개발 공부하면서 자주 쓰는 것 중 하나가 ArrayList다. 이 ArrayList는 리스트 안의 요소들을 String으로 만들어주는 toString()을 기본으로 갖고 있다.

그래서 1~10까지의 정수값만 갖는 ArrayList를 만들어봤다.

 

fun main()
{
    val list = arrayListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
}

이제 대충 println()으로 list.toString()하면 안의 숫자들이 출력될 것이다.

 

그런데 확장 함수는 애초에 클래스에 없던 함수를 새로 만든다는 뉘앙스의 단어다.

그래서 조건을 걸어보자 싶어서 5보다 작은 숫자들만 출력하는 함수를 확장 함수로 만들어보기로 했다.

일단 메서드니까 앞에 fun을 붙여주고, 그 다음에 메서드명을 써봤다.

 

fun getNumberUnderFive()
{
    //
}

정수값만 들어있는 리스트에서 값을 뺄 거니까 리턴값의 자료형은 int로 선언해야 한다.

그리고 ArrayList는 List 인터페이스의 구현체니까 ArrayList보다는 List를 메서드명 앞에 써줬다.

 

fun List<Int>.getNumberUnderFive(): ArrayList<Int>
{
    //
}

리턴값을 써주지 않아서 닫는 중괄호 밑에 빨간 줄이 생기지만 무시한다.

그 다음은 이제 내가 원하는 동작을 코드로 바꿔서 메서드 몸통에 써넣는 것 뿐이다.

 

/* 5보다 작은 값을 골라내서 출력하는 함수를 만들고 싶다 */
fun List<Int>.getNumberUnderFive(number: Int): ArrayList<Int>
{
    // 먼저 int형 데이터만 들어가게 ArrayList를 하나 파고
    var resultNum = arrayListOf<Int>()
    // for문으로 인자로 들어온 ArrayList를 받아서 이 크기만큼 반복한다
    for (numbers_in_for in this)
    {
        // 뭘 반복하는가? number(=5)보다 작은 값이 ArrayList 안에 보이면 새로 만든 ArrayList에 add()하는 것이다
        if (numbers_in_for < number)
        {
            // add()는 이 안에서 선언해야지
            resultNum.add(numbers_in_for)
        }
    }
    // for문이 다 돌면 resultNum에 담긴 것들을 리턴한다
    return resultNum
}

일단 생각나는 대로 짜봤다. 이제 메인에서 이 함수를 호출하고 결과를 보자.

 

fun main()
{
    val list = arrayListOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    println(list.toString())
    println(list.getNumberUnderFive(5))
}

 

결과는 아래와 같이 나왔다. 성공이다.

 

 

컬렉션 쪽에서 확장 함수를 쓴다면 이런 느낌으로 쓰면 되지 않을까 싶다. 뻑나거나 모르면 구글링하면 되지 뭐

 

 

그럼 이 확장 함수란 놈의 특징은 뭐가 있을까?

몇몇 포스팅들을 돌아보면서 정리한 결과 사람들이 공통적으로 똑같이 말하는 건 아래와 같았다.

 

  • 확장 함수는 static 메서드다
  • 확장 함수의 이름이 같은 경우 import할 때 이름을 바꿔야 한다. 바꿔도 동작은 잘 된다
  • 확장 함수와 클래스 멤버 함수(=클래스 안에 있던 함수)의 우선 순위를 따지면 클래스 멤버 함수가 더 높다
    그래서 이름 지을 때 기존 함수와 겹치지 않게 지어야 한다.
  • 만약 이름이 같아서 충돌난다면 as 키워드로 이름을 바꿀 수 있다
  • 확장 함수는 오버라이드 할 수 없다. 기존 클래스의 안에 선언되는 게 아니라 "밖"에 선언되는 거라서

 

나머진 아직 와닿지 않는 설명이라 쓰지 않았다. 다른 확장 함수들을 만들어보면서 익숙해질 시간을 가져야겠다.

반응형
Comments