이펙티브 코틀린 item 17: 이름 있는 아규먼트를 사용하라

woga·2023년 5월 21일
0

코틀린 공부

목록 보기
20/54
post-thumbnail

코드에서 아규먼트의 의미가 명확하지 않은 경우가 있다.

val text = (1..10).joinToString("I")

joinToString()에 대해 알고 있다면 "|"이 구분자라는 걸 알 것이다. 하지만 모른다면 접두사로 생각할 수도 있다.

파라미터가 불명확한 경우에는 이를 직접 지정해서 명확하게 만들 수 있다. 아래 코드처럼 이름 있는 아규먼트를 사용하면 된다.

val text = (1..10).joinToString(separator = "I")

또는 아래처럼 변수를 써서도 의미를 명확하게 할 수 있다.

val separator = "|"
val text = (1..10).joinToString(separator)

이름 있는 파라미터를 쓰면 더 신뢰할 수 있다. 변수명을 쓰는 방법도 개발자 의도를 쉽게 알 수 있지만 실제 코드에서 제대로 쓰이고 있는지는 알 수 없다. 변수를 잘못 만들 수도 있고 함수 호출 시 잘못된 위치에 배치할 수도 있다.

이름 있는 아규먼트는 이런 문제가 발생하지 않는다. 그래서 변수를 쓸 때도 이름 있는 아규먼트를 함께 활용하면 좋다.

val separator = "|"
val text = (1..10).joinToString(separator = separator)

이름 있는 아규먼트는 언제 써야 하는가?

이름 있는 아규먼트를 사용하면 코드가 길어지지만 2가지 장점이 생긴다.

이름을 기반으로 값이 뭘 나타내는지 알 수 있다
파라미터 입력 순서와 상관없으므로 안전하다

아규먼트 이름은 함수를 쓰는 개발자뿐 아니라 코드를 읽는 다른 사람들에게도 중요한 정보다.

sleep(100)

얼마나 sleep하는가? 100밀리초인지 100초인지 명확하지 않다. 이름 있는 아규먼트를 활용하면 명확해진다.

sleep(Millis(100))

타입은 이런 정보를 전달하는 좋은 방법이라고 할 수 있다. 만약 성능에 영향을 줄 거 같아서 걱정이라면 인라인 클래스를 사용하라. 하지만 여전히 파라미터 순서를 잘못 입력하는 등의 문제가 발생할 수 있다. 그래서 이름 있는 아규먼트를 추천한다. 특히 아래와 같은 경우에는 더 추천한다.

디폴트 아규먼트의 경우

같은 타입의 파라미터가 많은 경우
함수 타입의 파라미터가 있는 경우 (마지막 경우 제외)

디폴트 아규먼트의 경우

프로퍼티가 디폴트 아규먼트를 가질 경우 항상 이름을 붙여 쓰는 게 좋다. 일반적으로 함수명은 필수 파라미터들과 관련돼 있기 때문에 디폴트 값을 갖는 옵션 파라미터의 설명이 명확하지 않다. 따라서 이런 것들은 이름을 붙여 쓰는 게 좋다.

같은 타입의 파라미터가 많은 경우

파라미터가 모두 다른 타입이면 위치를 잘못 입력하면 오류가 발생할 것이므로 쉽게 문제를 발견할 수 있다. 하지만 파라미터에 같은 타입이 있다면 잘못 입력했을 때 문제를 찾아내기 어려울 수 있다.

fun sendEmail(to: String, message: String) { /**/ }

이런 함수가 있다면 이름 있는 아규먼트를 쓰는 게 좋다.

sendEmail(to = "abc@abc.com", message = "Hello, World!")

함수 타입 파라미터

함수 타입 파라미터는 조금 특별하게 다뤄야 한다. 일반적으로 함수 타입 파라미터는 마지막 위치에 배치하는 게 좋다.

함수명이 함수 타입 아규먼트를 설명해 주기도 한다. repeat()을 생각해 보라. repeat 뒤에 오는 람다는 반복될 블록을 나타낸다. thread도 그 후의 블록이 쓰레드 본문이라는 걸 쉽게 알 수 있다. 이런 이름들은 일반적으로 마지막에 위치하는 함수 파라미터에 대해서만 설명한다.

thread {
    // ...
}

그 밖의 모든 함수 타입 아규먼트는 이름 있는 아규먼트를 쓰는 게 좋다. 이렇게 하는 게 훨씬 이해하기 쉽다.

profile
와니와니와니와니 당근당근

0개의 댓글