본문 바로가기

Kotlin

Kotlin in Action - 함수 정의와 호출

1. 코틀린에서 컬렉션 만들기

  1. hashMapOf(1 to "One") 처럼 매핑, 여기서 to 는 일반 함수(Pair의 infix 함수) 
    @ infix: 연산자를 중간에 위치하는 기능
  2. 코틀린 자신만의 컬렉션 기능을 제공하지 않고 기존 자바 컬렉션을 활용한다.
    1. 이유: 기존 자바 컬렉션을 활용하면 자바 코드와 상호작용하기 쉽다.

2. 함수를 호출하기 쉽게 만들기

  1. 이름 붙인 인자
    1. 공백으로 값을 넘기는 경우 무슨 의미로 넘기는 지 알 수 없다. 특히 booelan 값은 더 그러므로 그 때는 Enum을 추천한다.
    2. 코틀린에서는 함수에 전달하는 인자 중 일부 또는 전부의 이름을 명시할 수 있다. 대신 하나라도 명시하면 그 뒤에 오는 모든 인자는 이름을 명시해야 한다.
  2. 디폴트 파라미터 값
    1. 자바에서 일부 클래스에 오버로딩한 메소드가 많은 문제로 어떤 함수가 불릴지 모호한 경우 발생 해결을 위해 사용
    2. 함수의 디폴트 파라미터 값은 호출하는 쪽이 아닌 선언하는 쪽에서 지정한다.
    3. 자바에서 디폴트 파라미터를 사용하려면 @JvmOverloads 어노테이션을 함수에 추가
  3. 정적인 유틸리티 클래스 없애기: 최상위 함수와 프로퍼리
    1. 코틀린은 유틸리티만 담은 클래스를 클래스를 만들 필요 없이 함수를 직접 소스파일의 최상위 수준에 위치시켜도 된다.
    2. JVM이 그 파일을 컴파일 할 때 새로운 클래스를 정의해준다.
      1. 최상위 함수가 들어있던 코틀린 소스 파일의 이름으로 만들어준다.
    3. 함수와 마찬가지로 프로퍼티도 최상위 수준에 놓을 수 있다.
      1. 주로 상수처럼 사용한다.
      2. 하지만 상수처럼 사용하는 프로퍼티가 getter ,setter 생기면 자연스럽지 못하므로 const 변경자를 사용해서 자바의 public static finalc처럼 사용한다.

3. 메소드를 다른 클래스에 추가: 확장 함수와 확장 프로퍼티

  • 기존 자바API를 재작성 하지 않고 코틀린이 제공하는 편리한 기능을 사용하기 위한 목적 
  • 확장할 클래스 이름: 수신 객체 타입
  • 확장 함수가 호출되는 대상이 되는 값: 수신 객체
  • 확장함수가 캡슐화를 깨지는 않는다.
  1. 임포트와 확장 함수
    1. 확장 함수를 정의한 것을 사용하려면 임포트 해야 한다.
    2. 확장 함수 이름은 짧은 이름을 사용
    3. as 키워드를 사용하면 임포트한 클래스나 함수를 다른 이름으로 사용할 수 있다.
      1. import strings.lastChar as last
        val c = "Kotlin".last()
      2. 임포트 할 때 이름을 바꾸는 것이 확장 함수 이름 충돌 해결 방안
  2. 자바에서 확장 함수 호출
    1. 내부적으로 확장함수는 수신 객체를 첫 번째 인자로 받는 정적 메소드다
    2. 확장 함수가 들어있는 파일이름으로 클래스 파일 결정
  3. 확장 함수로 유틸리티 함수 정의
    1. 확장 함수는 정적 메소드 호출에 대한 문법적인 편의
  4. 확장 함수는 오버라이딩 할 수 없다.
    1. 확장 함수는 클래스의 일부가 아니라 클래스 밖에 선언한다
      정적 : 컴파일 시점 / 동적 : 런타임 시점
    2. 무조건 타입이 가리키는 확장 함수가 실행된다.
    3. 확장함수와 멤버함수의 이름이 같다면 멤버함수가 호출된다.
  5. 확장 프로퍼티
    1. 단지 수신객체 클래스가 추가되었다.
    2. 게터와 세터를 명시적으로 호출해야 한다.

4. 컬렉션 처리: 가변 길이 인자, 중위 함수 호출, 라이브러리 지원

  • varang 키워드 사용하면 호출 시 인자 개수가 달리지는 함수 정의 가능
  • infix 함수 호출 구문을 사용하면 인자가 하나뿐인 메소드를 간편하게 호출 가능
  • 구조 분해 선언을 하면 복합적인 값을 분해해서 여러 변수에 나눠 담을 수 있다.
  1. 자바 컬렉션 API 확장
    1. 자바 컬렉션에 코틀린 새로운 기능을 추가한 것은 모두 확장함수로 구현
  2. 가변 인자 함수: 인자의 개수가 달라질 수 있는 함수 정의
    1. 자바에 ... 대신 코틀린에서는 vararg을 사용한다.
    2. 이미 배열에 들어있는 원소를 가변 인자로 넘길 때는 * 연산자를 배열 앞에 붙이면 된다
  3. 값의 쌍 다루기: 중위 호출과 구조 분해 선언
    1. mapOf에서 to를 사용한 것을 중위 호출이라고 한다.
    2. 수신객체와 메소드 인자 사이에 메소드 이름을 넣는다.
    3. infix 키워드를 함수 선언 앞에 추가
    4. 구조 분해 선언: 값을 변수로 구조 분해를 의미
      1. val (number, name) = 1 to "one"

5. 문자열과 정규식 다루기

  • 자바에다가 다양한 메서드 제공
  1. 문자열 나누기
    1. 자바에서 split(".") 의 결과가 split의 구분 문자열이 정규식이라서 빈 배열이 나온다.
    2. toRegex 확장 함수를 통해 문자열을 정규식으로 변환 가능
    3. split 확장 함수를 오버로딩 한 버전 중에 인자를 여러 개 받는 것도 있다.
  2. 정규식과 3중 따옴표로 묶은 문자열
    1. 정규식을 사용하지 않고도 라이브러리를 통해 쉽게 파싱할 수 있다.
    2. 3중 따옴표에서는 \\라고 쓰지 않고 \. 로만 사용해도 된다.
    3. MatchResult의 결과를 destructured 프로퍼티에 대입
  3. 여러 줄 3중 따옴표 문자열
    1. 테스트에서 유용하게 사용
    2. 소스코드에서 보기 좋게 하려면 문자열과 그 직전 공백 제거 함수인 trimMargin을 사용하면 된다.

6. 코드 다듬기: 로컬 함수와 확장

  • 코드 정리 방법으로 함수를 중첩시키는 방법을 생각했다.
  • 함수 내부에서 사용할 목적으로 코드의 중복을 줄이고, 검증까지 진행
  • 로컬 함수 - 바깥 파라미터 접근 - 확장 함수로 추출
  • 확장 함수를 로컬 함수로 정의할 수 있다.
  • 중첩은 한단계만 하는 것을 추천