公式の和訳(意訳)です.
- IDEでスタイルを設定する, ソースコード構成
- 命名規約
- フォーマット 前半(この記事)
- フォーマット 後半
- ドキュメントコメント,冗長な記述を避ける
- 慣用表現の使用
- ライブラリのコード規約
フォーマット
インデント
インデントするときはスペースを4つ空ける.
タブは使用しない.
波括弧は,開き括弧を構文がはじまる行の最後に書き,閉じ括弧を構文の開始位置と垂直位置を揃えて書く.
if (elements != null) {
for (element in elements) {
// ...
}
}
(注意:Kotlinでは,セミコロンは必須ではない.
そのため,改行は意味を持つ.
言語設計ではJavaスタイルの括弧が使用されているため、異なるフォーマットスタイルを使用しようとすると驚くような動作が発生するかもしれない).
水平方向の空白
二項演算子の前後には空白を書く(a + b
).
例外:"range to"演算子の前後にはスペースを書かない(0..i
).
単項演算子の前後にはスペースを書かない(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()
//
の後にはスペースを書く:// This is a comment
型パラメータを指定するための山括弧の前後にはスペースを空けない:class Map<K, V> { ...}
::
の前後にはスペースを空けない:Foo::class
,String::length
null許容型を示す?
の前にはスペースを空けない:String?
一般的な規則として,水平方向の位置揃えは避ける.
仮に異なる長さの名前をもつ識別子を用いたとしても,宣言その他一切のフォーマットに影響を及ぼすべきでない.
コロン
以下の場合では, :
の前にスペースを空ける.
- 型とサブタイプを区切るために使うとき
- 親クラスのコンストラクタか,同じクラスの異なるコンストラクタに処理を委譲するとき
- 予約語
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 { ... }
}
クラスヘッダ
クラスのコンストラクタのパラメータが少ないときは1行で書く.
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つ)を使う.
プライマリコンストラクタで宣言されたプロパティが, クラスの本体で宣言されたプロパティと同じインデントを持つことを保証するため.
修飾子の順序
宣言に複数の修飾子があるときは,以下の順序で書く.
public / protected / private / internal
expect / actual
final / open / abstract / sealed / const
external
override
lateinit
tailrec
vararg
suspend
inner
enum / annotation / fun // `fun interface` という形式の修飾子として `fun` を利用する場合
companion
inline / value
infix
operator
data
アノテーションはすべて修飾子の前に書く.
@Named("Foo")
private val foo: Foo
ライブラリを作成していない限り,冗長な修飾子は書かない(public
など).
アノテーション
アノテーションは,対象とする宣言より前に,宣言と同じインデントで,それぞれ別々の行に書く.
@Target(AnnotationTarget.PROPERTY)
annotation class JsonExclude
引数がないアノテーションは同じ行に書いてもよい.
@JsonExclude @JvmField
var x: String
アノテーションがひとつだけで,引数がないときは,対象とする宣言と同じ行に書いてもよい.
@Test fun foo() { ... }
ファイルアノテーション
ファイルアノテーションはファイルコメントより後, package
分より前に書く.
package
文とは1行空ける(パッケージではなく,ファイルを対象としたアノテーションであることを強調するためだ).
/** License, copyright and whatever */
@file:JvmName("FooBar")
package foo.bar
関数
関数が1行に収まらないときは,以下の構文に従う.
fun longMethodName(
argument: ArgumentType = defaultValue,
argument2: AnotherArgumentType
): ReturnType {
// body
}
関数のパラメータには,通常と同じインデント(スペース4つ)を使う.
コンストラクタパラメータと一貫性を保つためだ.
関数の本体がひとつの式であるときは,単一式関数(expression body)を使うほうが望ましい.
fun foo(): Int { // bad
return 1
}
fun foo() = 1 // good
単一式関数のフォーマット
単一式関数の宣言と本体が同じ行に書けないときは,=
を最初の行に書く.
式は次の行にインデント(スペース4つ)を空けて書く.
fun f(x: String, y: String, z: String) =
veryLongFunctionCallWithManyWords(andLongParametersToo(), x, y, z)