└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Kotlinコーディング規約 2 | 3 | # バージョン 4 | v1.0.1 5 | 6 | # 目次 7 | 8 | - はじめに 9 | - 命名規則 10 | - ファイルフォーマット 11 | - アクセス制御 12 | - クラス 13 | - 変数 14 | - 型 15 | - 制御 16 | - Nullable 17 | - エラーハンドリング 18 | - 関数・ラムダ 19 | - Javaとの相互間 20 | 21 | # はじめに 22 | 23 | このコーディング規約はKotlinがAndroid開発で使用されることを想定し、以下を方針として策定します。 24 | 25 | - プログラマーによるエラーの発生を防ぐ 26 | - コードの肥大化を防ぐ 27 | - コードの可読性を高くする 28 | - 美しいコードを保ち、発展させる 29 | 30 | # 命名規則 31 | 32 | ## パッケージ名 33 | 全て小文字で書く。 34 | また、ワイルドカードは使用禁止とする。 35 | 36 | **理由** 37 | ワイルドカードを使用すると、どのクラスを使用しているのかが不明確になる。 38 | 39 | 良い例 40 | 41 | ```kotlin 42 | package foo.bar 43 | ``` 44 | 45 | 悪い例 46 | 47 | ```kotlin 48 | package foo.* 49 | ``` 50 | 51 | ## クラス名 52 | UpperCamelCaseで書く。 53 | 54 | **理由** 55 | Kotlin公式Referenceに従う。 56 | 57 | 良い例 58 | 59 | ```kotlin 60 | class Empty 61 | ``` 62 | 63 | 悪い例 64 | 65 | ```kotlin 66 | class empty 67 | ``` 68 | 69 | ## オブジェクト名 70 | UpperCamelCaseで書く。 71 | 72 | **理由** 73 | Kotlin公式Referenceに従う。 74 | 75 | 良い例 76 | 77 | ```kotlin 78 | object DataProviderManager { 79 | ... 80 | } 81 | ``` 82 | 83 | 悪い例 84 | 85 | ```kotlin 86 | object dataProviderManager { 87 | ... 88 | } 89 | ``` 90 | 91 | ## インターフェース名 92 | UpperCamelCaseで書く。 93 | 94 | **理由** 95 | Kotlin公式Referenceに従う。 96 | 97 | 良い例 98 | 99 | ```kotlin 100 | interface MyInterface { 101 | ... 102 | } 103 | ``` 104 | 105 | 悪い例 106 | 107 | ```kotlin 108 | interface myInterface { 109 | ... 110 | } 111 | ``` 112 | 113 | ## データクラス名 114 | UpperCamelCaseで書く。 115 | 116 | **理由** 117 | Kotlin公式Referenceに従う。 118 | 119 | 良い例 120 | 121 | ```kotlin 122 | data class User( 123 | ... 124 | ) 125 | ``` 126 | 127 | 悪い例 128 | 129 | ```kotlin 130 | data class user( 131 | ... 132 | ) 133 | ``` 134 | 135 | ## シールドクラス名 136 | UpperCamelCaseで書く。 137 | 138 | **理由** 139 | Kotlin公式Referenceに従う。 140 | 141 | 良い例 142 | 143 | ```kotlin 144 | sealed class Expr { 145 | ... 146 | } 147 | ``` 148 | 149 | 悪い例 150 | 151 | ```kotlin 152 | sealed class expr { 153 | ... 154 | } 155 | ``` 156 | 157 | ## 関数・メソッド 158 | lowerCamelCaseで書く。 159 | 160 | **理由** 161 | Kotlin公式Referenceに従う。 162 | 163 | 良い例 164 | 165 | ```kotlin 166 | fun double(x: Int): Int { 167 | ... 168 | } 169 | ``` 170 | 171 | 悪い例 172 | 173 | ```kotlin 174 | fun Double(X: Int): Int { 175 | ... 176 | } 177 | ``` 178 | 179 | ## var・val 180 | lowerCamelCaseで書く。 181 | 但し、Companion Objectスコープ内に記述した定数(val)のみCONSTANT_CASEで書く。 182 | 183 | **理由** 184 | Kotlin公式Referenceに従う。 185 | 186 | 良い例 187 | 188 | ```kotlin 189 | class Person { 190 | val firstName = ... 191 | var lastName = ... 192 | 193 | val gender = ... 194 | 195 | companion object { 196 | var drinkAlcoholAge = ... 197 | 198 | const val GENDER_MALE = ... 199 | const val GENDER_FEMALE = ... 200 | } 201 | } 202 | ``` 203 | 204 | 悪い例 205 | 206 | ```kotlin 207 | class Person { 208 | val FirstName = ... 209 | var LastName = ... 210 | 211 | val Gender = ... 212 | 213 | companion object { 214 | var DRINK_ALCOHOL_AGE = ... 215 | 216 | const val GenderMale = ... 217 | const val GenderFemale = ... 218 | } 219 | } 220 | ``` 221 | 222 | ## 定数 223 | CONSTANT_CASEで書く。 224 | 225 | **理由** 226 | Kotlin公式Referenceに従う。 227 | 228 | 良い例 229 | 230 | ```kotlin 231 | const val SUBSYSTEM_DEPRECATED = "This subsystem is deprecated" 232 | ``` 233 | 234 | 悪い例 235 | 236 | ```kotlin 237 | const val subsystemDeprecated = "This subsystem is deprecated" 238 | ``` 239 | 240 | ## 列挙型 241 | 列挙型名はUpperCamelCase、各列挙型定数はCONSTANT_CASE書く。 242 | 243 | **理由** 244 | Kotlin公式Referenceに従う。 245 | 246 | 良い例 247 | 248 | ```kotlin 249 | enum class Direction { 250 | NORTH, SOUTH, WEST, EAST 251 | } 252 | ``` 253 | 254 | 悪い例 255 | 256 | ```kotlin 257 | enum class Direction { 258 | North, South, West, East 259 | } 260 | 261 | enum class direction { 262 | north, south, west, east 263 | } 264 | ``` 265 | 266 | ## Type変数 267 | 1文字または2文字の大文字で書く。 268 | 269 | **理由** 270 | Kotlin公式Referenceに従う。 271 | 272 | 良い例 273 | 274 | ```kotlin 275 | class Box(t: T) { 276 | var value = t 277 | } 278 | ``` 279 | 280 | 悪い例 281 | 282 | ```kotlin 283 | class Box(t: Type) { 284 | var value = t 285 | } 286 | ``` 287 | 288 | # ファイルフォーマット 289 | 290 | ## コロン 291 | 型情報、エルビス演算子の後ろのコロン(:)には半角スペースを入れ、前には入れない。 292 | それ以外のコロン(:)の前後には半角スペースを入れること。 293 | 294 | **理由** 295 | Kotlin公式Referenceに従う。 296 | 297 | 良い例 298 | 299 | ```kotlin 300 | class Child : MyInterface { 301 | var property: Int? = ... 302 | } 303 | ``` 304 | 悪い例 305 | 306 | ```kotlin 307 | class Child: MyInterface { 308 | var property : Int? = ... 309 | } 310 | ``` 311 | 312 | ## アノテーション 313 | ライブラリごとに1行改行して書く。 314 | 315 | **理由** 316 | 可読性のため。 317 | 318 | 良い例 319 | 320 | ```kotlin 321 | @LibraryA 322 | @LibraryB 323 | fun hoge() 324 | ``` 325 | 326 | 悪い例 327 | 328 | ```kotlin 329 | @LibraryA @LibraryB fun hoge() 330 | ``` 331 | 332 | ## セミコロンの使用禁止 333 | 行末のセミコロンの使用を禁止する。 334 | 335 | **理由** 336 | 不要なため。 337 | 338 | ## import順 339 | Android関連、ライブラリ、java/javaxの順で記載する。 340 | 341 | **理由** 342 | 可読性、コンフリクト防止のため。 343 | 344 | ##TODO・FIXMEの記載 345 | 346 | 未対応の機能には以下を記述すること。 347 | 348 | ```kotlin 349 | // TODO: 〜 350 | ``` 351 | 352 | 修正が必要な場合は以下を記述すること。 353 | 354 | ```kotlin 355 | // FIXME: 〜 356 | ``` 357 | 358 | **理由** 359 | 実装漏れを防止するため。 360 | 361 | # クラス 362 | 363 | ## シングルトン 364 | シングルトンのクラスを作成する場合、objectを利用すること。 365 | 366 | **理由** 367 | Kotlin公式Referenceに従う。 368 | 369 | ## this.でのアクセス 370 | 必要な時のみ使用すること。 371 | 372 | **理由** 373 | 統一し、冗長性を排除するため。 374 | 375 | 良い例 376 | 377 | ```kotlin 378 | class Person { 379 | val firstName = ... 380 | var lastName = ... 381 | 382 | fun printName() { 383 | print("$firstName $lastName") 384 | } 385 | 386 | fun changeName(firstName: String, lastName: String) { 387 | this.firstName = firstName 388 | this.lastName = lastName 389 | } 390 | } 391 | ``` 392 | 393 | 悪い例 394 | 395 | ```kotlin 396 | class Person { 397 | val firstName = ... 398 | var lastName = ... 399 | 400 | fun printName() { 401 | print("${this.firstName} ${this.lastName}") 402 | } 403 | } 404 | ``` 405 | 406 | # アクセス制御 407 | 408 | ## アクセス制御 409 | アクセス制御は可能な限りprivateを指定すること。 410 | 411 | **理由** 412 | そのクラス内、メソッド内…ということが担保でき、実装変更時の影響範囲を小さくできるため。 413 | 414 | # 変数 415 | 416 | ## 変数・定数の宣言 417 | var宣言を使用するのは、その値が変わり得る等、明確な理由があるときのみとする。 418 | それ以外の場合はval宣言を使用する。 419 | 420 | **理由** 421 | より安全なコードにし、意図しない値の変更を防ぐため。 422 | valを使用することでプログラマーが値が変わらないことを確認することができる。 423 | 逆に、varによって宣言された変数が変更されることを予期できる。 424 | 425 | ## 代替変数 426 | 代替変数(it)が使える場合は常に使用する。 427 | またitについて何を指しているか分からなくなることを避けるため 428 | 名前を付ける。 429 | 430 | **理由** 431 | 冗長性を排除し、シンプルなコードにするため。 432 | 433 | 良い例 434 | 435 | ```kotlin 436 | var x: String? = null 437 | ... 438 | x?.let { x -> 439 | print(x) 440 | } 441 | ``` 442 | 443 | 悪い例 444 | 445 | ```kotlin 446 | var x: String? = null 447 | ... 448 | x?.let { 449 | print(it) 450 | } 451 | ``` 452 | 453 | # 型 454 | 455 | ## 型推論 456 | 最大限利用すること。 457 | 458 | **理由** 459 | 冗長性を排除し、シンプルなコードにするため。 460 | 461 | 良い例 462 | 463 | ```kotlin 464 | val x = "X" 465 | ``` 466 | 467 | 悪い例 468 | 469 | ```kotlin 470 | val x: String = "X" 471 | ``` 472 | 473 | ## キャスト 474 | 左辺の型情報を省略すること。 475 | 476 | **理由** 477 | 冗長性を排除し、シンプルなコードにするため。 478 | 479 | 良い例 480 | 481 | ```kotlin 482 | val s = x as String 483 | ``` 484 | 485 | 悪い例 486 | 487 | ```kotlin 488 | val s: String = x as String 489 | ``` 490 | 491 | ## スマートキャスト 492 | スマートキャストが利用できる場合は常に使用すること。 493 | 494 | **理由** 495 | 冗長性を排除し、シンプルなコードにするため。 496 | 497 | 良い例 498 | 499 | ```kotlin 500 | if (x is String) { 501 | print(x.length) 502 | } 503 | ``` 504 | 505 | 悪い例 506 | 507 | ```kotlin 508 | if (x is String) { 509 | print((x as String).length) 510 | } 511 | ``` 512 | 513 | ## スマートオプショナル 514 | スマートオプショナルが利用できる場合は常に使用すること。 515 | 516 | **理由** 517 | 冗長性を排除し、シンプルなコードにするため。 518 | 519 | 良い例 520 | 521 | ```kotlin 522 | var x: String? = null 523 | ... 524 | x ?: return 525 | ``` 526 | 527 | 悪い例 528 | 529 | ```kotlin 530 | var x: String? = null 531 | ... 532 | if (x == null) { 533 | return 534 | } 535 | ``` 536 | 537 | # 制御 538 | 539 | ## When 540 | 値を1行で返す場合、{}を使用しないこと。 541 | 542 | **理由** 543 | 冗長性を排除し、シンプルなコードにするため。 544 | 545 | 良い例 546 | 547 | ```kotlin 548 | val x = when (type) { 549 | A -> “A” 550 | B -> “B“ 551 | } 552 | ``` 553 | 554 | 悪い例 555 | 556 | ```kotlin 557 | val x = when (type) { 558 | A -> { 559 | “A” 560 | } 561 | B -> { 562 | “B” 563 | } 564 | } 565 | ``` 566 | 567 | # Nullable 568 | 569 | ## Nullableの利用 570 | nullが入る可能性がない型にNullableを使用しないこと。 571 | 572 | **理由** 573 | nullアクセスの可能性をできるだけ下げるため。 574 | 575 | ## !!演算子 576 | 使用禁止とする。Nullableへのアクセスはsafe call(?.)を使うこと。 577 | 578 | **理由** 579 | NPEスローの可能性をできるだけ下げるため。 580 | 581 | 良い例 582 | 583 | ```kotlin 584 | var x: String? = null 585 | ... 586 | print("length: ${x?.length}") 587 | ``` 588 | 589 | 悪い例 590 | 591 | ```kotlin 592 | var x: String? = null 593 | ... 594 | print("length: ${x!!.length}") 595 | ``` 596 | 597 | # エラーハンドリング 598 | 599 | ## try-catch 600 | catchが空、もしくは「Exception e」のtry-catchは書いてはならない。 601 | 602 | **理由** 603 | アプリがクラッシュした理由が不明確になるため。 604 | 605 | # 関数・ラムダ 606 | 607 | ## letの利用 608 | スコープ関数letが利用できる場合は常に使用すること。 609 | 610 | **理由** 611 | 冗長性を排除し、シンプルなコードにするため。 612 | 613 | 良い例 614 | 615 | ```kotlin 616 | var x: Int? = null 617 | ... 618 | 619 | val result = x?.let { x * 2 } ?: 0 620 | ``` 621 | 622 | 悪い例 623 | 624 | ```kotlin 625 | var x: Int? = null 626 | ... 627 | 628 | val result = if (x != null) { 629 | x * 2 630 | } else { 631 | 0 632 | } 633 | ``` 634 | 635 | ## ラムダの利用 636 | ()内でなく、()外に書く。 637 | 638 | **理由** 639 | Kotlin公式Referenceに従う。 640 | 641 | 良い例 642 | 643 | ```kotlin 644 | list.filter {it > 10}.map { element -> element * 2} 645 | ``` 646 | 647 | 悪い例 648 | 649 | ```kotlin 650 | list.filter({ 651 | it > 10 652 | }).map({ 653 | element -> element * 2 654 | }) 655 | ``` 656 | 657 | ## Unitの省略 658 | 関数の戻り値がUnitの場合、Unitの記述を省略すること。 659 | 660 | **理由** 661 | 冗長性を排除し、シンプルなコードにするため。 662 | 663 | 良い例 664 | 665 | ```kotlin 666 | fun hoge() { 667 | ... 668 | } 669 | ``` 670 | 671 | 悪い例 672 | 673 | ```kotlin 674 | fun hoge(): Unit { 675 | ... 676 | } 677 | ``` 678 | 679 | ## Single Line関数 680 | 値を1行で返すような関数の場合、{}でなく=を使用すること。 681 | また、戻り値の型がNullableかどうかを明示するため省略してはならない。 682 | 683 | **理由** 684 | 冗長性を排除し、シンプルなコードにするため。 685 | 686 | 良い例 687 | 688 | ```kotlin 689 | fun foo(a: Int, b: Int): Int = a + b 690 | ``` 691 | 692 | 悪い例 693 | 694 | ```kotlin 695 | fun foo(a: Int, b: Int) = a + b 696 | 697 | fun foo(a: Int, b: Int): Int { 698 | return a + b 699 | } 700 | ``` 701 | 702 | # Javaとの相互間 703 | 704 | ## ゲッターとセッター 705 | Javaクラスのプロパティを利用する際、get〜、set〜でなくプロパティ名で直接アクセスすること。 706 | 707 | **理由** 708 | 冗長性を排除し、シンプルなコードにするため。 709 | 710 | 良い例 711 | 712 | ```kotlin 713 | // Java側 714 | class Person { 715 | private String name; 716 | 717 | public String getName() { 718 | return this.name; 719 | } 720 | 721 | public String setName(String name) { 722 | this.name = name; 723 | } 724 | } 725 | 726 | // Kotlin側 727 | val person = Person() 728 | person.name = "Name" 729 | print(person.name) 730 | ``` 731 | 732 | 悪い例 733 | 734 | ```kotlin 735 | // Java側 736 | class Person { 737 | private String name; 738 | 739 | public String getName() { 740 | return this.name; 741 | } 742 | 743 | public String setName(String name) { 744 | this.name = name; 745 | } 746 | } 747 | 748 | // Kotlin側 749 | val person = Person() 750 | person.setName("Name") 751 | print(person.getName()) 752 | ``` 753 | --------------------------------------------------------------------------------