Kotlin 공식 문서 살펴보기 (4) - Coding conventions 2
08 Jan 2022주석
-
긴 주석은
/**
로 시작해서 각 줄마다*
로 시작/** * 여러 줄에 걸친 * 문서 주석 예제입니다. */
-
짧은 주석은 한 줄 가능
/** 짧은 문서 주석 */
-
보통
@param
,@return
태그를 사용 지양 -
매개변수와 반환 값 설명을 주석에 직접 설명
-
매개변수가 언급될 때마다 링크 추가
-
@param
,@return
은 본문 흐름에 맞지 않는 긴 설명이 필요할 때만 사용// 아래 방법은 지양하도록 한다. /** * Returns the absolute value of the given number. * @param number The number to return the absolute value for. * @return The absolute value. */ fun abs(number: Int) { ... } // 아래 방법을 사용하도록 한다. /** * Returns the absolute value of the given [number]. */ fun abs(number: Int) { ... }
중복 구성 피하기
Unit 반환 타입
-
함수가
Unit
을 반환할 경우, 반환 타입은 반드시 생략fun foo() { // Unit 이 생략됨 ... }
세미콜론
- 가능하면 세미콜론 생략
문자열 템플릿
-
단순한 변수를 넣을 때 중괄호 사용 지양
-
중괄호는 오직 긴 표현식을 쓸 때만 사용
println("$name hjas ${children.size} children")
관용적 사용
불변성
-
변경 가능한 데이터 사용보다 변경 불가능한 데이터 사용 선호
-
초기화 후에 수정되지 않는다면, 항상 지역 변수나 속성은
val
로 선언 -
변경되지 않는 콜렉션을 선언할 때는 항상 변경 불가능한 콜렉션 인터페이스(
Collection
,List
,Set
,Map
) 사용 -
콜렉션 인스턴스를 생성하기 위해 팩토리 함수를 사용할 때는 가능하면 변경할 수 없는 콜렉션을 반환하도록 함
// Bad fun validateValue(actualValue: String, allowedValues: HashSet<String>) { ... } // Good fun validateValue(actualValue: String, allowedValues: Set<String>) { ... } // Bad val allowedValues = arrayListOf("a", "b", "c") // Good val allowedValues = listOf("a", "b", "c")
매개변수 기본값
-
오버로드된 함수를 선언하는 것보다 매개변수 기본값이 선언된 함수를 선언하는 것 선호
// Bad fun foo() = foo("a") fun foo(a: String) { ... } // Good fun foo(a: String = "a") { ... }
Type aliases
-
함수형 타입 또는 여러 번 사용되는 타입 매개변수가 있는 타입이 있을 경우, 타입 별명 정의
typealias MouseClickHandler = (Any, MouseEvent) -> Unit typealias PersonIndex = Map<String, Person>
-
이름 충돌을 막기 위해 private 또는 내부 타입 별명을 사용할 때는 패키지와 import에서 언급된
import ... as ...
선호
람다 매개변수
- 짧고 중첩되지 않은 람다에서는
it
사용 권장 - 매개변수가 있는 중첩 람다에서는 항상 매개변수 명시적 선언
명명된 인자
-
메서드에서 같은 기본형의 여러 매개변수가 있거나
Boolean
타입 매개변수가 있을 때는 이름을 가진 인자 사용drawSquare(x = 10, y = 10, width = 100, height = 100, fill = true)
조건문
-
try
,if
,when
의 표현 형식 사용 선호if (x) return foo() else return bar() // Preferred return if (x) foo() else bar()
when (x) { 0 -> return "zero" else -> return "nonzero" } // Preferred return when(x) { 0 -> "zero" else -> "nonzero" }
if vs. when
-
이진 조건에서는
when
대신if
사용if (x == null) ... else ...
-
3개 이상의 조건일 있을 때는
when
when (x) { 1 -> ... 2 -> ... 3 -> ... else -> ... }
조건에서 null일 수 있는 Boolean 값
- null일 수 있는
Boolean
값을 조건문에서 사용할 때는if (value == true)
또는if (value == false)
검사 사용
루프
- 루프보다 고차원 함수(
filter
,map
등) 사용 선호 - 예외
forEach
- 일반적인
for
루프 선호 - forEach 수신자가 nullable 하거나 긴 호출 체인의 일부일 때 제외
범위에서 루프
-
열린 범위에서는
until
사용for (i in 0..n - 1) { .. } // bad for (i in 0 until n) { .. } // good
문자열
-
문자열 연결보다 문자열 템플릿 선호
-
\n
를 일반 문자열 리터럴에 포함하는 것보다 여러 줄 문자열 선호 -
결과 문자열에 내부 들여쓰기가 필요하지 않을 경우, 여러 줄의 들여쓰기를 유지할 때
trimIndent
사용 -
내부 들여쓰기가 필요할 때는
trimMargin
사용println(""" Not trimmed text """ ) println(""" Trimmed Text """.trimIndent() ) println() val a = """Trimmed to margin text: |if(a > 1) { | return a |}""".trimMargin() println(a)
// 출력 결과 Not trimmed text Trimmed text Trimmed to margin text: if(a > 1) { return a }
함수 vs. 속성
- 어떤 경우에는 매개변수가 없는 함수는 읽기 전용 속성으로 교체 가능
- 함수보다 속성을 선호하는 경우
- throw 하지 않음
- 계산 비용이 저렴하거나 처음 실항할 때 캐싱됨
- 객체 상태가 바뀌지 않을 경우 호출할 때 동일한 결과 반환
중위 함수
- 비슷한 역할을 하는 두 객체에서 작동할 때만
infix
함수 선언- 좋은 예:
and
,to
,zip
- 나쁜 예:
add
- 좋은 예:
- 수신자 객체를 변경한다면
infix
로 선언하지 않도록 함
팩토리 함수
-
클래스를 위해 팩토리 함수를 선언할 때 클래스와 같은 이름을 쓰지 않도록 함
-
팩토리 함수 동작이 특별한 이유를 명확히 하는 고유한 이름 사용
-
특별한 의미가 없을 때만 클래스와 같은 이름 사용 가능
class Point(val x: Double, val y: Double) { companion object { fun fromPolar(angle: Double, radius: Double) = Point(...) } }
-
다른 슈퍼클래스 생성자를 호출하지 않고 여러 오버로드된 생성자가 있는 클래스가 있고 기본 인자 값이 있는 하나의 생성자로 줄일 수 없는 경우에는 오버로드된 생성자를 팩토리 함수로 바꾸는 것이 좋음
플랫폼 타입
-
플랫폼 타입의 표현식을 반환하는 public 함수나 메서드는 kotlin 타입을 명시적으로 선언해야 함
fun apiCall(): String = MyJavaApi.getProperty("name")
-
플랫폼 타입의 표현식으로 초기화되는 모든 패키지 레벨 또는 클래스 레벨의 속성은 kotlin 타입을 명시적으로 선언해야 함
class Person { val name: String = MyJavaApi.getProperty("name") }
-
플랫폼 타입의 표현식으로 초기화된 로컬 값은 타입 선언이 있을수도 있고 없을수도 있음
fun main() { val name = MyJavaApi.getProperty("name") println(name) }
스코프 함수
- 주어진 객체의 컨텍스트에서 코드 블록을 실행하는 함수
let
,run
,with
,apply
,also