본문 바로가기
개발

TIL: Kotlin컨벤션

by kks950115 2023. 11. 27.
728x90

Kotlin 컨벤션

언어에 맞춤법이 있듯이 코드를 치는데도 맞춤법 비스무리한 게 있다.  이렇게 쓰자하고 합의한 것들. 이렇게 안해도 작동은 하지만 내가 아닌 다른 사람들이 볼 때 매우매우 불편하므로 지켜주는 게 좋다.

예를 들자면 "이렇게붙여써도뜻은문제가없지만읽을때매우불편하다"  와 "이렇게 붙여 써도 뜻은 문제가 없지만 읽을 때 매우불편하다" 중에 어떤 것이 더 읽기 편한가? 그러니 되도록 가이드에 맞게 쓰는 게 좋다.

 

소스파일 UTF-8 인코딩

이클립스를 처음 깔고 파일을 열었을 때 외계어가 나왔던 기억이 난다... 표준으로 맞춰준다.

 

이름 지정

// MyClass.kt
class MyClass { }


// Bar.kt
class Bar { }
fun Runnable.toBar(): Bar = // …


// Map.kt
fun <T, O> Set<T>.map(func: (T) -> O): List<O> = // …
fun <T, O> List<T>.map(func: (T) -> O): List<O> = // …


// extensions.kt
fun MyClass.process() = // …
fun MyResult.print() = // …

클래스는 파스칼 케이스로 짓는다.  (파일 이름이 복수형인 경우 camelCase가 허용됨)

 

특수문자

  • 문자열과 문자 리터럴의 모든 다른 공백 문자는 이스케이프 처리됩니다.
  • 탭 문자는 들여쓰기에 사용되지 않습니다.

 

해당 특수문자에 상응하는 특수 이스케이프문이 있을 경우 유니코드 문자 대신 사용합니다.

 

비 ASCII 문자

직접 쓸 수 있다면 유니코드를 쓰지 말고 직접 써야한다. 주석으로 어떤 것인지 알려줘야 한다.

 

 

구조

각 섹션은 빈 줄 하나를 사용하여 구분한다.

 

 

저작권/라이선스

//OK!!!
/*
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
 
 //NO!!!!
 /**
 * Copyright 2017 Google, Inc.
 *
 * ...
 */
 
  //NO!!!!
 // Copyright 2017 Google, Inc.
//
// ...

 

여러줄 주석을 쓴다.

 

Import문

줄바꿈이 허용되지 않는다.

 

중괄호

if (string.isEmpty()) return     // Okay

val result =         // Okay
    if (string.isEmpty()) DEFAULT_VALUE else string   

when (value) {     // Okay
    0 -> return     
    // …
}



if (string.isEmpty())
    return  // WRONG!    쓸거면 붙여서 써야한다. 한줄 띄면 안된다.

if (string.isEmpty()) {
    return  // Okay    
}

if (string.isEmpty()) return  // WRONG      else도 붙여서 써야한다. 띄면 안된다.
else doLotsOfProcessingOn(string, otherParametersHere)        

if (string.isEmpty()) {
    return  // Okay
} else {
    doLotsOfProcessingOn(string, otherParametersHere)
}

 

 

비어있지 않은 블록

비어 있지 않은 블록과 블록 형식 구문에서는 중괄호가 K&R(Kernighan and Ritchie) 스타일('이집트 대괄호')을 따른다.

  • 중괄호로 구문이 종료되거나 함수, 생성자 또는 named 클래스의 본문이 종료되는 경우에만 닫는 중괄호 뒤에 줄바꿈이 있습니다. 예를 들어 중괄호 뒤에 else 또는 쉼표가 온다면 중괄호 뒤에 줄바꿈이 없습니다.
return Runnable {
    while (condition()) {   //여는 중괄호
        foo()					
    }    					//닫는 중괄호. 이렇게 써야한다.
}

return object : MyClass() {
    override fun foo() {      //(..) 뒤에 중괄호 한칸 띄어야한다. 
        if (condition()) {   //(..) 뒤에 중괄호 한칸 띄어야한다. 
            try {
                something()
            } catch (e: ProblemException) {  //중괄호 뒤에 catch가 오면 띄어쓰기 할 필요X. 여는 중괄호
                recover()
            }
        } else if (otherCondition()) {
            somethingElse()
        } else {              // 중괄호 뒤에 else가 오면 줄바꾸기 할 필요X. }와 else는 한칸 띄워준다.
            lastThing()
        }					  //닫는 중괄호. 
    }
}

 

 

if-else문

표현식이 각각 한개일 때만 한줄에 중괄호를 생략해서 넣을 수 있다.

 

val value = if (string.isEmpty()) 0 else 1  // Okay

val value = if (string.isEmpty())  // WRONG!
    0
else
    1
    
    
===================  
val value = if (string.isEmpty()) { // Okay
    0
} else {
    1
}

 

한줄에 한 구문

세미콜론은 쓰지 않는다.

 

함수

fun <T> Iterable<T>.joinToString(
    separator: CharSequence = ", ",     //안으로 4칸 띄기
    prefix: CharSequence = "",
    postfix: CharSequence = ""
): String {
    // …
}

//------------------------------------------------
override fun toString(): String {   //이거를...
    return "Hey"
}



override fun toString(): String = "Hey"   // 이렇게 쓸 수도 있다.

 

공백

// WRONG!
for(i in 0..1) {
}

// Okay
for (i in 0..1) {  // 0..1은 모두 붙여쓴다.
}


// WRONG!
val two = 1+1

// Okay
val two = 1 + 1



// WRONG!
ints.map { value->value.toString() }

// Okay
ints.map { value -> value.toString() }


// WRONG!
val toString = Any :: toString

// Okay
val toString = Any::toString

// WRONG!
val oneAndTwo = listOf(1,2)    

// Okay
val oneAndTwo = listOf(1, 2)  //,뒤엔 띄어쓰기

// WRONG!
class Foo :Runnable

// Okay
class Foo : Runnable      //:뒤엔 띄어쓰기

 

 

유형주석

@Retention(SOURCE)
@Target(FUNCTION, PROPERTY_SETTER, FIELD)     //인수가 있을 경우 줄바꿈을 해준다.
annotation class Global


@JvmField @Volatile    // 인수가 없으면 줄바꿈 안해도 된다.
var disposable: Disposable? = null


@Volatile var disposable: Disposable? = null   //인수가 없는 유형주석이 하나 뿐이면 한줄에 입력 가능

@Test fun selectAll() {
    // …
}

 

 

상수

상수는  UPPER_SNAKE_CASE로 작성한다.

const val NUMBER = 5
val NAMES = listOf("Alice", "Bob")
val AGES = mapOf("Alice" to 35, "Bob" to 32)
val COMMA_JOINER = Joiner.on(',') // Joiner is immutable
val EMPTY_ARRAY = arrayOf()


//상수가 아니면 camelCase로 작성
val variable = "var"
val nonConstScalar = "non-const"
val mutableCollection: MutableSet = HashSet()
val mutableElements = listOf(mutableInstance)
val mutableValues = mapOf("Alice" to mutableInstance, "Bob" to mutableInstance2)
val logger = Logger.getLogger(MyClass::class.java.name)
val nonEmptyArray = arrayOf("these", "can", "change")
728x90
반응형

댓글