티스토리 뷰
1. Source code organization (소스 코드 구성)
1.1 Directory structure(디렉토리 구조)
- 혼합 언어 프로젝트에서의 Kotlin 소스 파일은 Java 소스 파일과 동일한 소스 루트에 있어야 하며 동일한 디렉토리 구조 를 따라야 한다. (각 파일은 각 패키지 명령문에 해당하는 디렉토리에 저장되어야 합니다.)
- 순수한 Kotlin 프로젝트에서 권장되는 디렉토리 구조는 공통 루트 패키지가 생략 된 패키지 구조를 따랴아 한다.
- 공통 패키지 명을 뺀 나머지 패키지 구조를 따른다.
- 공통 패키지 : com.example.kotlin = root 디렉토리
- 서브 패키지 : com.example.kotlin.foo.bar = foo/bar 디렉토리
- 모든 소스 파일은 UTF-8로 인코딩 되어야 합니다.
1.2 Source file names(소스 파일 이름)
Kotlin 파일에 하나의 클래스(관련 최상위 수준의 선언이 포함 될 수 있음) 가 포함 된 경우 해당 파일의 이름은 클래스 이름과 동일해야 하며 .kt 확장자가 추가되어야 합니다.
Kotlin 파일에 여러 클래스 또는 최상위 레벨 선언만 포함되어 있으면 파일에 포함 된 것을 설명하는 이름으로 파일 이름을 지정해야 합나다.
// 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> = // …
- 카멜 표기법 사용 (CamelCase)
- 예시 파일명 : ProcessDeclarations.kt
- 파일 이름은 코드가 하는 것들을 설명해야 합니다.. 따라서 “Util”과 같은 의미 없는 단어를 사용하지 말라고 권장합니다.
1.3 Source file organization(소스 파일 구성)
- 연관되어 진 여러 선언(클래스, 최상위 함수 또는 속성)을 동일한 Kotlin 소스 파일에 포함하나, 파일 크기가 너무 크지 않고 수백 줄을 초과하지 않아야 한다
- 클래스에 모든 클라이언트와 관련된 클래스의 확장 함수를 넣을 때 클래스 자체에 정의 된 동일한 파일에 이 함수를 넣는 것이 좋습니다.
- 특정 클라이언트에 대해서만 의미가 있는 확장 기능을 정의할 때는 해당 클라이언트 코드 옆에 확장 기능을 지정합니다.
1.4 Class layout(클래스 레이아웃)
- 일반적으로 클래스의 내용은 다음 순서로 정렬합니다.
- 속성 선언 및 Initializer 블록
- 보조 생성자
- 메소드 선언
- Companion Object(동반자 객체) : Kotlin에서는 정적 선언을 할 수 없지만, 클래스를 초기화하지않고 내부의 코드에 접근해야 한다거나, 팩토리 메소드를 구현해야 할 경우 Companion Object를 사용하여 구현할 수 있습니다.
- 메소드 선언은 사전 순 또는 가시성에 따라 정렬하지 말고, 일반 메소드와 확장 메소드를 분리하지 않습니다.
- 연관된 메소드끼리 함께 위치하도록 구성해야 합니다. 다른 사람이 봤을 때 로직을 이해하기 쉽도록 배치합니다.
- 중첩 클래스는 해당 클래스를 사용하는 코드 다음에 배치 합니다.
- 중첩 클래스가 외부에서만 사용하도록 의도되어 있고, 클래스 내부에서 참조되지 않은 경우 Companion Object(동반자 객체) 뒤의 끝에 넣습니다.
1.5 Interface implementation layout(인터페이스 구현 레이아웃)
- 인터페이스를 구현할 할 때 구현 멤버들의 순서를 인터페이스 멤버와 동일한 순서로 유지합니다.
- 필요한 경우, 구현에 사용되는 privated method 들을 배치합니다.
1.6 Overload layout
항상 각 클래스 다음에 넣습니다.
2. Naming rules (이름 지정 규칙)
Java naming convention 을 따름
Package
- 항상 소문자로 권장 (com.example.project)
- 일반적으로 권장하지는 않지만, 여러 단어를 사용해야 할 경우 간단히 병합하거나 카멜 표기법 사용(com.example.myProject)
Class, Object : 카멜 표기법 사용(첫 문자a는 대문자)
object EmptyDeclarationProcessor : DeclarationProcessor() { ... }
2.1 Function names (함수 이름)
함수, 속성 및 지역 변수의 이름은 소문자로 시작하여 카멜 표기법을 사용하며, 밑줄은 사용하지 않습니다.
var declarationCount = ...
클래스의 인스턴스를 만드는데 사용되는 팩토리 함수는 생성되는 클래스 이름과 동일할 수도 있습니다.
class FooImpl : Foo { ... } fun Foo(): Foo { return FooImpl(...) }
2.2 Names for test methods (테스트 메소드의 이름)
테스트 코드의 경우 메소드에 backtick(`), space, underscore(_)를 사용할 수 있습니다.
class MyTestCase { @Test fun `ensure everything works`() { } @Test fun ensureEverythingWorks_onAndroid() { } }
2.3 Property names (속성 이름)
상수 : 대문자와 _(underscore) 사용 가능
const val MAX\_COUNT = 8 val USER\_NAME\_FIELD = "UserName"
변경 가능한 데이터를 가진 객체 : 카멜 표기법
val mutableCollection: MutableSet = HashSet()
싱글톤 객체 : 객체 선언과 동일하게 사용
val PersonComparator: Comparator = …
enum 상수
enum class Color { RED, GREEN }
2.4 Names for backing properties
클래스가 개념상으로 동일하지만 하나는 public API의 일부이고, 다른 하나는 구현 세부 정보가 있는 private property 이름은 접두사로 _(underscore)를 사용합니다.
private 속성을 반환하는 public 속성을 사용하는 경우, private 속성 앞에 _(underscore)를 붙여 사용합니다.
class C { private val _elementList = mutableListOf<Element>() val elementList: List<Element> get() = _elementList }
2.5 Choosing good names (좋은 이름 선택)
- 클래스
- 무엇을 하는 클래스인지 의미를 표현
- 명사 또는 명사구의 이름을 사용(List, PersonReader)
- 메소드
- 어떤 변화 또는 객체의 반환 작업을 하는 메소드인지 표현
- 동사 또는 동사구의 이름을 사용(close, readPersons)
- 선언 이름의 일부가 약어인 경우
- 약어가 두 문자인 경우는 대문자로 표기(IOStream)
- 더 긴 경우는 첫번째 문자만 대문자로 사용(XmlFomatter, HttpInputStream)
3. Formatting (서식 지정)
대부분의 경우 Java code convention 을 따름
4 spaces 사용, 탭은 사용하지 않습니다.
중괄호의 경우 구성 시작부분의 끝줄에 여는 중괄호를 입력하고, 열린 구성과 수직적으로 정렬된 별도의 줄을 닫는 중괄호를 입력한다.
세미콜론은 선택사항이지만 생략하는 것을 권장
if (elements != null) { for (element in elements) { // ... } }
3.1 Horizontal whitespace (가로 공백)
연산자 앞, 뒤에 공백을 추가합니다.
- a + b, a / b
- 예외
- “range to” 연산 주위에도 공백을 넣지 말아야 합니다. (0..I)
- 단항 연산 주위에도 공백을 넣지 말아야 합니다. (a++)
중괄호 앞에 공백을 추가 합니다.
- if, when, for and while
괄호 앞에는 공백을 추가하지 않습니다.
class A(val x: Int) fun foo(x: Int) { } fun bar() { foo(1) }
(, [ 뒤에 또는 ), ] 전에 공백을 추가하지 않습니다.
. 또는 ?. 주위에 공백을 추가하지 않습니다.
foo.bar().filter { it > 2 }.joinToString() foo?.bar()
주석 // 뒤에 공백을 추가 합니다.
// 주석을 추가합니다.
3.2 Colon
타입과 슈퍼 타입을 분리할 때 공백을 추가합니다.
슈퍼 클래스 생성자나 같은 클래스의 다른 생성자에 위임할 때 공백을 추가 합니다.
object 키워드 다음에 공백을 추가 합니다.
항상 : 뒤에 공백을 추가합니다.
속성과 해당 타입을 분리할 때는 앞에 공백을 추가하지 않습니다.
abstract class Foo : IFoo { abstract fun foo(a: Int): T } class FooImpl : Foo() { constructor(x: String) : this(x) { // ... } val x = object : IFoo { ... } }
3.3 Class header formatting
기본 생성자의 매개 변수가 몇 개 있는 클래스는 한 줄로 작성할 수 있습니다.
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() {} }
클래스 헤더가 길 때 클래스 헤더와 본문을 명확하게 구분하려면 클래스 헤더 다음에 빈 줄을 넣거나 여는 중괄호를 별도의 줄에 넣습니다.
class MyFavouriteVeryLongClassHolder : MyLongHolder<MyFavouriteVeryLongClass>(), SomeOtherInterface, AndAnotherOne { fun foo() {} }
- 생성자의 매게 변수에는 일반 들여 쓰기(4 공백)을 사용합니다.
- 이유 : 기본 생성자에서 선언 된 속성이 클래스 본문에 선언 된 속성 만큼 들여 쓰기가 되도록 해야 합니다.
3.4 Modifiers(수정자)
선언에 여러 수정자가 있는 경우 항상 다음 순서로 입력해야 합니다.
public / protected / private / internal expect / actual final / open / abstract / sealed / const external override lateinit tailrec vararg suspend inner enum / annotation companion inline infix operator data
모든 특수 효과를 수정자 앞에 배치하도록 합니다.
@Named("Foo") private val foo: Foo
- 라이브러리에서 작업하지 않는 한 중복 수정자 (예: public) 를 생략합니다.
3.5 Annotation formatting
어노테이션은 일반적으로 별개의 줄에 붙습니다. 단, 어노테이션이 첨부 된 문장과 같은 들여쓰기가 있어야 합니다.
@Target(AnnotationTarget.PROPERTY) annotation class JsonExclude
인수가 없는 어노테이션은 같은 줄에 배치할 수 있습니다.
@JsonExclude @JvmField var x: String
인수가 없는 단일 어노테이션은 해당 선언과 동일한 줄에 배치할 수 있습니다.
@Test fun foo() { ... }
3.6 File annotation
파일 어노테이션은 package 명령문 앞에 배치되며 빈 줄이 있는 package 와 구분합니다. (package가 아닌 파일을 대상으로 한다는 사실을 강조하기 위함)
/\*\* License, copyright and whatever \*/ @file:JvmName("FooBar") package foo.bar
3.7 Function formatting
함수 시그니쳐가 한 줄에 들어가지 않으면 다음 구문을 사용하도록 합니다.
fun longMethodName( argument: ArgumentType = defaultValue, argument2: AnotherArgumentType ): ReturnType { // body }
함수 매개 변수에 일반 들여 쓰기(4 공백)을 사용하도록 합니다.
- 생성자와 매게 변수와의 일관성을 두기 위함
하나의 표현식으로 구성된 본문이 있는 함수에 표현식 본문을 사용하는 것이 좋습니다.
fun foo(): Int { // bad case return 1 } fun foo() = 1 // good case
3.8 Expression body formatting
함수에 선언된 동일한 행에 맞지 않는 표현식 본문이 있다면 첫 행에 = 부호를 붙입니다.
표현 본문을 4칸만큼 들여 씁니다.
fun f(x: String) = x.length
3.9 Property formatting
매우 간단한 읽기 전용 속성의 경우 한 줄 형식을 고려하도록 합니다.
val isEmpty: Boolean get() = size == 0
복잡한 속성의 경우 항상 get 및 set 키워드를 별도의 줄에 넣습니다.
val foo: String get() { // ... }
initializer가 있는 속성의 경우 initializer가 길면 등호 다음에 줄 바꿈을 추가하고 initializer를 4칸만큼 들여 씁니다.
private val defaultCharset: Charset? = EncodingRegistry.getInstance().getDefaultCharsetForPropertiesFiles(file)
3.10 Formatting control flow statements
if 또는 when문의 조건이 여러 행인 경우 항상 명령문 본문 주위에 중괄호를 사용합니다.
명령문 begin에 상대적인 4칸 공백으로 조건의 각 후속줄을 들여쓰기 합니다.
조건의 닫는 괄호와 여는 중괄호를 별도의 줄에 넣습니다.
if (!component.isSyncing && !hasAnyKotlinRuntimeInScope(module) ) { return createKotlinNotConfiguredPanel(module) }
이전의 중괄호와 같은 줄에 else, catch, finally 키워드와 do/while 루프의 while 키워드를 넣습니다.
if (condition) { // body } else { // else part } try { // body } finally { // cleanup }
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() // good case false -> { baz() } // bad case }
3.11 Method call formatting
긴 인수 목록에서는 여는 괄호 다음에 줄 바꿈을 넣도록 합니다.
인수는 4칸 들여씁니다.
같은 줄에 여러 가지 밀접하게 관련된 인수를 그룹화 하도록 합니다.
인수 이름과 값을 구분하는 = 기호 주위에 공백을 넣도록 합니다.
drawSquare( x = 10, y = 10, width = 100, height = 100, fill = true )
3.12 Chained call wrapping
별도로 묶여있는 변수를 선언할 때는 문자 또는 ?. 연산자 다음 행에 하나의 들여쓰기를 하도록 합니다.
체인의 첫 번째 호출은 일반적으로 앞에 줄 바꿈이 있어야 하지만 코드를 생략하도 무방합니다.
val anchor = owner ?.firstChild!! .siblings(forward = true) .dropWhile { it is PsiComment || it is PsiWhiteSpace }
3.13 Lambda formatting
람다식에서 매게 변수를 본문에 분리하는 화살표 주위와 중괄호 주위에 공백을 사용합니다.
호출이 단일 람다로 사용되면 가능할 때 마다 괄호 밖으로 전달이 되어야 합니다.
list.filter { it > 10 }
람다 레이블을 할당하는 경우 레이블과 여는 중괄호 사이에 공백을 두지 않습니다.
fun foo() { ints.forEach lit@{ // ... } }
여러 줄에 람다에서 매게 변수 이름을 선언할 때는 첫 번째 줄에 이름을 넣고 그 다음에 화살표와 줄 바꿈을 넣습니다.
appendCommaSeparated(properties) { prop -> val propertyValue = prop.get(obj) // ... }
매게 변수 목록이 너무 길어 한 줄에 들어갈 수 없는 경우 화살표를 별도의 줄에 입력하도록 합니다.
foo { context: Context, environment: Env -> context.configureEnv(environment) }
4. Documentation comments (문서 주석)
더 긴 문서 주석을 보려면 별도의 행에 /** 를 입력하고 각 후속 행을 시작하도록 합니다.
/** * This is a documentation comment * on multiple lines. */
짧은 주석은 한 줄에 입력할 수 있습니다.
/\*\* This is a short documentation comment. \*/
일반적으로 @param, @return 태그를 사용하지 않도록 합니다.
대신 매개 변수 설명 및 반환 값을 설명서 주석에 직접 통합하고 매개 변수에 대한 링크를 언급한 곳마다 추가하도록 합니다.
주 텍스트의 흐름이 맞지 않는 긴 설명이 필요한 경우에만 @param, @return을 사용하도록 합니다.
// Avoid doing this: /** * 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) = ... // Do this instead: /** * Returns the absolute value of the given [number]. */ fun abs(number: Int) = ...
Copyright / License 주석
/ * * Copyright 2017 Google, Inc. * * * * /
5. Avoiding redundant constructs (중복 구성 피하기)
- 일반적으로 Kotlin의 특정 구문 구조가 선택사항이며 IDE에서 중복으로 강조 표시된 경우 코드에서 생략해야 합니다.
- 명확성을 위해 코드에 불필요한 구문 요소를 남겨두지 않습니다.
5.1 Unit
함수가 Unit을 반환하면 반환 유형을 생략해야 합니다.
fun foo() { // ": Unit" is omitted here
}
5.2 Semicolons
- 가능한 경우 세미콜론을 생략하도록 합니다.
5.3 String templates
문자열 템플릿에 간단한 변수를 삽입할 때는 중괄호를 사용하지 않습니다.
더 긴 표현식에 대해서만 중괄호를 사용합니다.
println("$name has ${children.size} children")
6. Idiomatic use of language features (언어 기능의 관용적 사용)
6.1 Immutability(불변성)
변경할 수 없는 데이터를 가변적으로 사용하는 것이 바람직합니다.
초기화 후 로컬 변수와 속성이 수정되지 않으면 항상 var 대신 val을 사용하도록 합니다.
변경되지 않는 컬렉션을 선언하려면 항상 불변 컬렉션 인터페이스를 사용합니다. (Collection, List, Set, Map)
팩토리 함수를 사용하여 컬렉션 인스턴스를 만들 때는 가능한 불변 컬렉션 유형을 반환하는 함수를 사용합니다.
// Bad: use of mutable collection type for value which will not be mutated fun validateValue(actualValue: String, allowedValues: HashSet) { ... } // Good: immutable collection type used instead fun validateValue(actualValue: String, allowedValues: Set) { ... } // Bad: arrayListOf() returns ArrayList, which is a mutable collection type val allowedValues = arrayListOf("a", "b", "c") // Good: listOf() returns List val allowedValues = listOf("a", "b", "c")
6.2 Default parameter values(기본 매개 변수 값)
Overload 된 함수를 선언할 때는 기본 매개 변수 값을 사용하여 함수를 선언하는 것이 좋습니다.
// Bad case fun foo() = foo("a") fun foo(a: String) { ... } // Good case fun foo(a: String = "a") { ... }
6.3 Type aliases(별칭 유형)
코드베이스에서 여러 번 사용되는 유형의 매개 변수가 있다면 typealias를 사용하는 것이 좋습니다.
typealias MouseClickHandler = (Any, MouseEvent) -> Unit typealias PersonIndex = Map<String, Person>
6.4 Lambda parameters
- 짧고 중첩되지 않은 람다에서는 매게 변수를 명시적으로 선언하는 대신 it 규칙을 사용하는 것이 좋습니다.
- 매개 변수가 있는 중첩 된 람다에서 매개 변수는 항상 명시적으로 선언되어야 합니다.
6.5 Returns in a lambda
- 람다에서 라벨이 지정된 여러 개의 리턴을 사용하지 않도록 합니다.
- 람다를 재구성하여 단일 리턴을 갖도록 해야 합니다.
- 단일 리턴이 불가능한 경우 익명 함수로 변환하는 것을 고려하도록 합니다.
- 람다에서 마지막 문장에 레이블이 지정된 리턴 값을 사용하지 않도록 합니다.
6.6 Named arguments
모든 매개 변수의 의미가 문맥에서 절대적으로 명확하지 않다면 메소드가 동일한 기본 유형의 여러 매개 변수
또는 Boolean 유형의 매개 변수를 사용하는 경우 Named arguments로 개수와 상관없이 원하는 위치에 값을 대입할 수 있습니다.
drawSquare(x = 10, y = 10, width = 100, height = 100, fill = true)
6.7 Using conditional statements
if, if 및 when의 조건문을 사용하는 것이 좋습니다.
return if (x) foo() else bar() return when(x) { 0 -> "zero" else -> "nonzero" }
위의 내용은 다음과 같은 경우에 적합합니다.
if (x) return foo() else return bar() when(x) { 0 -> return "zero" else -> return "nonzero" }
6.8 if or when
binary conditions의 경우 when 대신에 if를 사용하는것이 좋습니다.
when (x) { null -> ... else -> ... } if (x == null) ... else ...
세 가지 이상의 옵션이 있는 경우는 when의 사용을 선호합니다.
6.9 Using nullable Boolean values in conditions (조건에 nullable Boolean 값 사용)
- 조건문에 Nullable Boolean를 사용해야 하는 경우라면 if (value == true) 또는 if (value == false)를 사용합니다.
6.10 Using loops(루프 사용하기)
- higher-order 함수를 루프에 사용하는 것이 좋습니다.(filter, map 등)
예외 : forEach(forEach 의 수신자가 nullable 이거나 더 긴 체인 호출의 일부로 사용되지 않는 한 일반적으로 for loop를 대신 사용하는 것을 선호합니다.)
6.11 Loops on ranges(범위의 루프)
until 함수를 사용해서 열린 범위를 반복하도록 합니다.
for (i in 0..n - 1) { ... } // bad case for (i in 0 until n) { ... } // good case
6.12 Using strings
문자열 템플릿을 사용하는 것이 좋습니다.
\n escape sequences 을 사용하는 대신에 다중 행을 사용하는 것을 권장합니다.
여러 줄의 문자열에서 들여 쓰기를 유지하려면 trimMargin, trimIndent 를 사용합니다.
assertEquals("Foo Bar".trimIndent(), value) val a = "if(a > 1) { | return a |}".trimMargin()
6.13 Functions vs Properties
인수가 없는 함수는 읽기 전용 속성과 호환될 수 있습니다.
의미는 비슷하지만 서로를 선호할 때는 규칙이 있습니다.
기본 알고리즘이 다음과 같은 경우 함수에 대한 속성을 선호합니다
throw 하지 않습니다.
0(1) 복잡도
쉬운 계산 또는 첫 번째 실행에서 캐싱
객체 상태가 변경되지 않은 경우 호출에 대한 동일한 결과를 반환합니다.
6.14 Using extension functions (확장 기능 사용)
- 확장 기능을 자유롭게 사용합니다.
- 주로 객체에 대해 작동하는 함수가 있을 때 마다 객체를 receiver로 받아들이는 확장 함수를 고려해야 합니다.
- API 오염을 최소화 하기 위해 확장 함수의 가시성을 가능한 많이 제한해야 합니다.
- 필요한 경우 로컬 확장 함수, 멤버 확장 함수 또는 비공개 가시성이 있는 최상위 확장 함수를 사용하도록 합니다.
6.15 Using infix functions (중위 함수 사용)
- 비슷한 역활을 하는 두 개의 객체에서 작동 할 때만 infix function을 선언합니다.
- 좋은 예 : and, zip
- 나쁜 예 : add
- 메소드가 receiver object를 변경하면 삽입을 선언하면 안됩니다.
6.16 Factory functions
클래스에 대한 팩토리 함수를 선언하는 경우 클래스 자체와 동일한 이름을 지정하면 안됩니다.
고유한 이름을 사용하여 팩토리 함수의 이유를 명확히 해야 합니다.
class Point(val x: Double, val y: Double) { companion object { fun fromPolar(angle: Double, radius: Double) = Point(...) } }
- 다른 슈퍼 클래스 생성자를 호출하지 않고 기본 인수값을 사용하여 단일 생성자로 축소할 수 없는 여러 Overload 된 생성자가 있는 경우 Overload 된 생성자를 팩토리 함수로 대체하는 것이 좋습니다.
6.17 Platform types
플랫폼 유형의 식을 리턴하는 경우 공용 함수/메소드는 Kotlin 유형을 명시적으로 선언해야 합니다.
fun apiCall(): String = MyJavaApi.getProperty("name")
플랫폼 유형의 표현식으로 초기화 된 모든 패키지(패키지 또는 클래스 수준)는 명시적으로 Kotlin 유형을 선언해야 합니다.
class Person { val name: String = MyJavaApi.getProperty("name") }
플랫폼 형식으로 초기화 된 값은 형태 선언을 가질 수도 있고 가지지 않을 수도 있습니다.
fun main(args: Array) { val name = MyJavaApi.getProperty("name") println(name) }
6.18 Using scope functions apply/with/run/also/let (범위 함수 사용)
Kotlin은 주어진 객체의 Context에서 코드 블록을 실행하는 다양한 함수를 제공합니다.
블록의 여러 객체에서 메소드를 호출하거나 Context의 인스턴스를 인수로 전달하고 있는 경우 this 사용
receiver가 블록에서 전혀 사용되지 않는 경우는 also 사용
// Context object is 'it' class Baz { var currentBar: Bar? val observable: Observable val foo = createBar().also { currentBar = it // Accessing property of Baz observable.registerCallback(it) // Passing context object as argument } }
```
// Receiver not used in the block
val foo = createBar().also {
LOG.info("Bar created")
}
// Context object is 'this'
class Baz {
val foo: Bar = createBar().apply {
color = RED // Accessing only properties of Bar
text = "Foo"
}
}
```
실행의 결과가 Context Object 일 필요가 있는 경우 apply 사용
블록에서 값을 반환해야 할 경우 with, let 또는 run 사용
// Return value is context object class Baz { val foo: Bar = createBar().apply { color = RED // Accessing only properties of Bar text = "Foo" } } // Return value is block result class Baz { val foo: Bar = createNetworkConnection().let { loadBar() } }
Context Object가 Nullable 일 경우 apply 또는 run 사용
체인의 호출 결과로 정해지는 경우 with 또는 also 사용
// Context object is nullable person.email?.let { sendEmail(it) } // Context object is non-null and accessible directly with(person) { println("First name: $firstName, last name: $lastName") }
7. Coding conventions for libraries (라이브러리의 코딩 규칙)
- 멤버의 가시성을 항상 명시적으로 지정해야 합니다. (선언을 실수로 공개 API에 노출시키지 않도록 합니다.)
- 항상 함수 반환 형식 및 속성 형식을 명시적으로 지정합니다. (구현이 변경될 때 실수로 반환 형식을 변경하지 않도록 합니다.)
- 새로운 문서를 필요로 하지 않는 재정의를 제외하고는 모든 공용 멤버에 대한 KDoc 주석을 제공합니다. (라이브러리에 대한 문서 생성 지원을 위함)
참고
https://kotlinlang.org/docs/reference/coding-conventions.html
https://developer.android.com/kotlin/style-guide
http://open2jang.tistory.com/30
http://theeye.pe.kr/archives/2619
'프로그래밍 > Kotlin' 카테고리의 다른 글
[Kotlin] 고차함수 / 람다식, 코틀린의 다양한 함수 알아보기 (0) | 2020.03.15 |
---|---|
[Kotlin] 변수와 자료형 / 연산자 (0) | 2020.03.15 |
[Kotlin] 컬렉션(Collection) (0) | 2018.12.30 |
[Kotlin] 기본 자료형 2 (0) | 2018.12.25 |
[Kotlin] 기본 자료형 1 (0) | 2018.12.17 |
- Total
- Today
- Yesterday
- 1237
- 10757
- 10827
- constraintlayout
- 문자열
- 2743
- 알고리즘
- 최대공약수와 최소공배수
- algorithm
- 10826
- mssql
- #kotlin
- kotlin
- 단어 길이 재기
- 1158
- a^b
- #android #motionlayout
- 1260
- 자동타입
- GCD 합
- Eclipse
- javacv
- 큰 수 A+B
- 함수형사고 Kotlin Java
- OpenCV
- 10828
- 피보나치 수 4
- 조세퍼스 문제
- algorihtm
- 영상처리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |