kotlin Coding conventions

Untitled·2022년 5월 27일
0

Kotlin

목록 보기
1/1
post-thumbnail

kotlin Coding convention 문서를 번역해봤다....

일반적으로 알려지고 따르기 쉬운 코딩컨벤션은 프로그래밍 언어에 필수적입니다. Kotlin을 사용하는 프로젝트의 코드 스타일 및 코드 구성에 대한 지침을 제공합니다.

IDE Style 구성

  • Mac OS 기준
  1. commend + , Preferences 메뉴
  2. Editor > Code Style > Kotlin
  3. Set From 클릭 후 Kotlin style guide

소스 코드 구성

디렉토리 구조

순수한 Kotlin 프로젝트에서 권장되는 디렉토리 구조는 공통 루트 패키지가 생략된 패키지 구조를 따릅니다.

소스 파일 이름

Kotlin 파일에 단일 클래스가 포함된 경우(최상위 선언이 있을 수 있다) , 이름은 .kt 확장자가 포함된 클래스 이름과 동일해야 한다. 파일에 여러 클래스가 포함되어 있거나 최상위 선언만 포함된 경우 파일에 포함되어 있는 내용을 설명하는 이름을 선택하고 그에 따라 파일 이름을 저장합니다.

파일 이름은 파일이 수행하는 작업의 설명을 꼭 포함해야 한다. 그러므로 Util 과 같이 의미 없는 단어는 피하는 것이 좋다.

소스 파일 구성

동일한 kotlin 소스 안에 다중 선언 (클래스, 최상위 함수, 속성)을 배치하는 것은 서로 의미적으로 밀접하게 관련되어 잇고 파일 크기가 합리적으로(수백 줄을 넘지 않을 경우) 유지되는 한 권장된다.

특히, 클래스와 모든 클라이언트와 관련된 클래스에 대한 확장 함수를 정의할 때 클래스와 동일한 파일에 넣습니다. 특정 클라이언트에만 의미 있는 확장 함수일 경우 클라이언트 코드 옆에 배치합니다. 일부 클래스의 모든 확장을 갖기 위해 파일을 생성하지 마세요~

클래스 레이아웃

다음과 같은 순서로 진행되어야 한다.

  1. 속성 선언 및 초기화 블록
  2. 보조 생성자
  3. 메소드 선언
  4. 컴패니언 객체 (static 대신 쓰는애..?)

메소드 선언을 알파벳순 또는 가시성 기준으로 정렬하지 말고 일반 메소드를 확장 메소드와 분리하지 마세요. 대신에 관련 내용을 모아서 클래스 처음부터 끝까지 읽은 후 무슨 일을 하고 있는 소스인지 논리적으로 따를 수 있도록 만드세요. 순서를 선택하고(높은 수준의 항목 먼저 선택하거나 반대의 경우에도) 해당 명령을 따라라!

해당 클래스를 사용하는 코드 옆에 중첩 클래스를 배치한다. 클래스가 외부에서 사용되도록 의도되고 내부에서는 참조되지 않는 경우 컴패니언 객체 끝에 넣는다.

인터페이스 구현 레이아웃

인터페이스를 구현할 때 구성원을 인터페이스 구성원과 동일한 순서로 유지하세요(필요한 경우 추가로 구현되는private 메소드)

Overload 레이아웃

항상 클래스 옆에 오버로드를 배치한다.

네이밍(명명) 규칙

Kotlin의 패치키와 클래스 네이밍 규칙은 매우 간단합니다.

  • 패치키 이름은 항상 소문자이며 밑줄을 사용하지 않는다.(org.example.project) 여러 단어로 된 이름을 용하는 것은 일반적으로 권장하지 않지만 필요할 경우 Camel Case을 사용한다.(org.example.myProject)

  • 클래스 및 객체 이름은 대문자로 시작하고 Camel Case를 사용한다.

open class DeclarationProcessor { /*...*/ }

object EmptyDeclarationProcessor : DeclarationProcessor() { /*...*/ }

함수 이름

함수, 속성 및 지역 변수의 이름은 소문자로 시작하고 밑줄 없이 Camel Case 사용한다.

fun processDeclarations() { /*...*/ }
var declarationCount = 1

예외 : 클래스 인스턴스를 생성하는데 사용도는 팩토리 함수는 추상 return type과 동일한 이름을 가질 수 있다.

interface Foo { /*...*/ }

class FooImpl : Foo { /*...*/ }

fun Foo(): Foo { return FooImpl() }

테스트 메소드명

테스트에서 백틱(물결 아래있는거) 묶인 공백이 있는 메소드명을 사용할 수 있다. 이러한 메소드명은 안드로이드 런타임에서 지원해주지 않는다. 메소드명의 밑줄도 테스트 코드에서는 허용된다.

class MyTestCase {
     @Test fun `ensure everything works`() { /*...*/ }

     @Test fun ensureEverythingWorks_onAndroid() { /*...*/ }
}

프로퍼티명

상수명은 밑줄로 구분된 대문자를 사용한다. Snake Case

const val MAX_COUNT = 8
val USER_NAME_FIELD = "UserName"

동작 또는 변경 가능한 데이터가 있는 객체를 보유하는 최상위 또는 객체 속성의 이름은 Camel Case를 사용한다.

val mutableCollection: MutableSet<String> = HashSet()

Object 싱글톤 객체에 대한 참조를 갖고 있는 속성의 이름은 선언과 동일한 네이밍을 사용할 수 있다.

val PersonComparator: Comparator<Person> = /*...*/

열거형 상수의 경우 사용법에 따라 밑줄로 구분된 snake case 및 대문자 camel case 사용한다.

###지원 속성명
클래스에 개념적으로 동일한 두개의 속성이 있지만 하나는 공용 API의 일부이고 다른 하나는 구현 세부 정보인 경우 개인 속성에 접두사로 밑줄을 붙인다.

class C {
    private val _elementList = mutableListOf<Element>()

    val elementList: List<Element>
         get() = _elementList
}

좋은 네이밍

~~ 블라블라 ~~

Formatting

들여쓰기

들여쓰기의 경우 네개의 공백을 사용하고 탭은 사용하지 마세요.

중괄호의 경우 여는 중괄호를 구문이 시작하는 줄 끝에 놓고 닫는 중괄호는 여는 구문과 수평으로 정렬된 별도의 줄에 놓는다.

if (elements != null) {
    for (element in elements) {
        // ...
    }
}

코틀린에서는 세미콜론이 선택 사항이라 줄 바꿈이 중요하다. 언어 디자인은 자바 스타일 중괄호를 사용하며 다른 스타일을 사용하면 놀라운 일이 펼쳐진다..!

가로 공백

  • 이항 연산자 ( a + b ) 주위에 공백을 넣는다 예외 범위 연산자 주위에는 공백을 넣지마세요 0..i
  • 단항 연산자 주위에 공백 X a++
  • 제어 흐름 키워드( if, when, for, while)와 여는 괄호 사이에 공백을 넣는다.
  • 기본 생성자 선언, 메서드 선언 또는 메서드 호출에서 여는 괄호 앞에 공백을 두지마세요.
class A(val x: Int)

fun foo(x: Int) { ... }

fun bar() {
    foo(1)
}
  • 괄호 사이에 공백 두지마세요
  • ., ?.: foo.bar().filter { it > 2 }.joinToString(), foo?.bar() 사이에 공백 두지마세요.
  • 주석 뒤에 공백 넣기
  • 타입 매개변수 사용 시 꺽쇠 괄호 주위에 공백 두지 마세요.
  • :: 주위에 공백 두지 마세요.
  • nullable ? 형식 사용하기 전에 공백 두지 마세요.

일반적으로 어떤 종류의 수평 정렬도 피하세요. 식별자 이름의 길이를 줄이는 것은 선언이나 사용법 형식에 영향을 미치지 말아야 합니다.

콜론 :

: 의 경우 앞에 공백을 둔다.

  • 타입과 상위타입 유형을 구별할 경우
  • 슈퍼클래스 생성자나 같은 클래스의 다른 생성자에게 위임할 때
  • Object 키워드 뒤
    :선언과 해당 유형을 구분할 때 공백을 두지 말고 뒤에 공백을 넣어라!
abstract class Foo<out T : Any> : IFoo {
    abstract fun foo(a: Int): T
}

class FooImpl : Foo() {
    constructor(x: String) : this(x) { /*...*/ }

    val x = object : IFoo { /*...*/ }
}

클래스 헤더

몇 가지 정도의 매개변수가 있는 생성자는 한 줄로 작성할 수 있다.

class Person(id: Int, name: String)

긴 헤더가 있는 클래스는 매개변수 별로 들여쓰기를 사용해 표현해야한다. 또한 닫는 괄호는 새 줄에 있어야 한다. 상속을 사용하는 경우 슈퍼클래스 생성자 호출 또는 구현된 인터페이스와 같은 줄에 있어야 한다!

class Person(
    id: Int,
    name: String,
    surname: String
) : Human(id, name) { /*...*/ }

다중 인터페이스의 경우 슈퍼클래스 생성자 호출이 먼저 위치해야 하고 다른 인터페이스는 다른 라인에 작성한다.

class Person(
    id: Int,
    name: String,
    surname: String
) : Human(id, name),
    KotlinMaker { /*...*/ }

긴 상위타입 리스트가 있는 클래스의 경우 콜론 뒤에 줄 바꿈을 넣고 모든 상위타입을 수평으로 정렬한다.

class MyFavouriteVeryLongClassHolder :
    MyLongHolder<MyFavouriteVeryLongClass>(),
    SomeOtherInterface,
    AndAnotherOne {

    fun foo() { /*...*/ }
}
profile
그저 그런 꾸준히 하고만 싶은 개발자 이야기

0개의 댓글