Kotlin 코딩 컨벤션 가이드
Kotlin 프로그래밍 언어를 사용할 때 따라야 할 코딩 컨벤션에 대한 종합적인 가이드입니다.
이 가이드라인을 따르면 코드의 일관성과 가독성을 높일 수 있습니다.
이 가이드 문서는 공식 홈페이지를 참고하였습니다.
https://kotlinlang.org/docs/coding-conventions.html
Kotlin 명명 규칙 및 포맷팅 가이드
Kotlin에서 코드를 작성할 때 일관성 있고 가독성 높은 코드를 만들기 위한 명명 규칙과 포맷팅 가이드라인을 소개합니다.
1. 명명 규칙
패키지와 클래스 이름
- 패키지 이름은 항상 소문자로 작성하며 밑줄을 사용하지 않습니다. (예: org.example.project)
- 여러 단어로 된 패키지 이름은 권장하지 않지만, 필요한 경우 카멜 케이스를 사용합니다. (예: org.example.myProject)
- 클래스와 객체 이름은 대문자로 시작하고 카멜 케이스를 사용합니다.
open class DeclarationProcessor { /*...*/ }
object EmptyDeclarationProcessor : DeclarationProcessor() { /*...*/ }
함수와 변수 이름
- 함수, 프로퍼티, 지역 변수의 이름은 소문자로 시작하고 카멜 케이스를 사용합니다.
fun processDeclarations() { /*...*/ }
var declarationCount = 1
테스트 메서드 이름
- 테스트 코드에서는 백틱(`)으로 둘러싼 공백이 포함된 메서드 이름을 사용할 수 있습니다
class MyTestCase {
@Test fun `ensure everything works`() { /*...*/ }
@Test fun ensureEverythingWorks_onAndroid() { /*...*/ }
}
상수 이름
- 상수(const로 표시된 프로퍼티 또는 불변 데이터를 담는 최상위/객체 val 프로퍼티)는 대문자와 밑줄로 구분된 이름을 사용합니다.
const val MAX_COUNT = 8
val USER_NAME_FIELD = "UserName"
백킹 프로퍼티 이름
- 공개 API의 일부인 프로퍼티와 구현 세부사항인 프로퍼티가 개념적으로 같은 경우, 비공개 프로퍼티 이름 앞에 밑줄을 사용합니다.
class C {
private val _elementList = mutableListOf<Element>()
val elementList: List<Element>
get() = _elementList
}
2. 포맷팅
들여쓰기
- 4개의 공백을 사용하며, 탭은 사용하지 않습니다.
- 중괄호는 구문이 시작하는 줄의 끝에 놓고, 닫는 중괄호는 별도의 줄에 놓습니다.
if (elements != null) {
for (element in elements) {
// ...
}
}
가로 공백
- 이항 연산자 주위에 공백을 넣습니다. (예: a + b)
- 제어 흐름 키워드(if, when, for, while)와 여는 괄호 사이에 공백을 넣습니다.
- 주 생성자 선언, 메서드 선언, 메서드 호출의 여는 괄호 앞에는 공백을 넣지 않습니다.
class A(val x: Int)
fun foo(x: Int) { ... }
fun bar() {
foo(1)
}
콜론
- 타입과 슈퍼타입을 구분할 때, 생성자 위임 시, object 키워드 뒤에 콜론 앞에 공백을 넣습니다.
- 선언과 그 타입을 구분할 때는 콜론 앞에 공백을 넣지 않습니다.
- 콜론 뒤에는 항상 공백을 넣습니다.
abstract class Foo<out T : Any> : IFoo {
abstract fun foo(a: Int): T
}
클래스 헤더 포맷팅
- 짧은 헤더는 한 줄에 작성합니다.
- 긴 헤더는 각 주 생성자 매개변수를 별도의 줄에 작성하고, 닫는 괄호는 새 줄에 놓습니다.
class Person(id: Int, name: String)
class Person(
id: Int,
name: String,
surname: String
) : Human(id, name) { /*...*/ }
수식어 순서
선언에 여러 수식어가 있는 경우, 다음 순서를 따릅니다:
- public / protected / private / internal
- expect / actual
- final / open / abstract / sealed / const
- external
- override
- lateinit
- tailrec
- vararg
- suspend
- inner
- enum / annotation / fun (fun interface의 수식어로)
- companion
- inline / value
- infix
- operator
- data
모든 애노테이션은 수식어 앞에 배치합니다.
@Named("Foo")
private val foo: Foo
애노테이션
- 애노테이션은 해당 선언 앞에 별도의 줄에 같은 들여쓰기로 배치합니다.
@Target(AnnotationTarget.PROPERTY)
annotation class JsonExclude
인자가 없는 여러 애노테이션은 같은 줄에 배치할 수 있습니다.
@JsonExclude @JvmField
var x: String
인자가 없는 단일 애노테이션은 해당 선언과 같은 줄에 배치할 수 있습니다.
@Test fun foo() { /*...*/ }
파일 애노테이션
파일 애노테이션은 파일 주석 다음, 패키지 문 앞에 위치하며, 패키지 문과는 빈 줄로 구분합니다.
/** License, copyright and whatever */
@file:JvmName("FooBar")
package foo.bar
함수
- 함수 시그니처가 한 줄에 맞지 않으면 다음과 같이 작성합니다:
fun longMethodName(
argument: ArgumentType = defaultValue,
argument2: AnotherArgumentType,
): ReturnType {
// 본문
}
- 함수 매개변수는 4칸 들여쓰기를 사용합니다.
- 단일 표현식으로 구성된 함수는 표현식 본문을 사용합니다.
fun foo(): Int { // 나쁜 예
return 1
}
fun foo() = 1 // 좋은 예
표현식 본문
함수의 표현식 본문이 선언과 같은 줄에 맞지 않으면, = 기호를 첫 줄에 두고 표현식 본문을 4칸 들여씁니다.
fun f(x: String, y: String, z: String) =
veryLongFunctionCallWithManyWords(andLongParametersToo(), x, y, z)
속성
- 매우 간단한 읽기 전용 속성은 한 줄로 포맷팅합니다:
val isEmpty: Boolean get() = size == 0
더 복잡한 속성은 get과 set 키워드를 별도의 줄에 배치합니다:
val foo: String
get() { /*...*/ }
초기화 구문이 긴 속성은 = 기호 다음에 줄 바꿈을 하고 4칸 들여씁니다:
private val defaultCharset: Charset? =
EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file)
제어 흐름 문
- 여러 줄의 if나 when 조건문에는 항상 중괄호를 사용하고, 조건의 각 줄을 4칸 들여씁니다. 닫는 괄호와 여는 중괄호는 별도의 줄에 배치합니다:
if (!component.isSyncing &&
!hasAnyKotlinRuntimeInScope(module)
) {
return createKotlinNotConfiguredPanel(module)
}
else, catch, finally 키워드와 do-while 루프의 while 키워드는 이전 중괄호와 같은 줄에 배치합니다:
if (condition) {
// 본문
} else {
// else 부분
}
try {
// 본문
} finally {
// 정리
}
when 문에서 여러 줄의 분기는 인접한 case 블록과 빈 줄로 구분합니다:
private fun parsePropertyValue(propName: String, token: Token) {
when (token) {
is Token.ValueToken ->
callback.visitValue(propName, token.value)
Token.LBRACE -> { // ...
}
}
}
짧은 분기는 중괄호 없이 조건과 같은 줄에 배치합니다:
when (foo) {
true -> bar() // 좋은 예
false -> { baz() } // 나쁜 예
}
메소드 호출
긴 인자 목록은 여는 괄호 다음에 줄 바꿈을 하고, 인자를 4칸 들여씁니다. 관련 있는 인자들은 같은 줄에 그룹화합니다:
drawSquare(
x = 10, y = 10,
width = 100, height = 100,
fill = true
)
인자 이름과 값을 구분하는 = 기호 주위에 공백을 둡니다.
연쇄 호출
연쇄 호출을 줄 바꿈할 때는 . 문자나 ?. 연산자를 다음 줄에 한 칸 들여써서 배치합니다:
val anchor = owner
?.firstChild!!
.siblings(forward = true)
.dropWhile { it is PsiComment || it is PsiWhiteSpace }
체인의 첫 번째 호출은 보통 그 앞에 줄 바꿈을 하지만, 코드가 더 이해하기 쉬워진다면 생략해도 됩니다.
'개발&프로그래밍' 카테고리의 다른 글
[Kotlin] 숫자 타입과 연산 가이드 (4) | 2024.08.10 |
---|---|
[kotlin] 코딩 컨벤션 - lambdas, Trailing commas (0) | 2024.08.10 |
[kotlin] 자주 사용되는 관용구(idiom) 모음 (0) | 2024.08.09 |
[kotlin] 입문시 알아야 할 8가지 핵심 문법 (0) | 2024.08.07 |
[kotlin] 입문시 알아야 할 7가지 핵심 문법 (0) | 2024.08.07 |
댓글