Unofficial Kotlin Style Guide

Nick Apperley
3 min readMay 2, 2017

--

With the official Kotlin documentation there is an official style guide however it is incomplete/insufficient. This article attempts to provide guidelines for code that is Kotlinic, Kotlin code that is written as Idiomatic Kotlin which is done using a good style. Some programming languages like Java don’t have an official style guide. Note that this article is currently a draft version.

Some of the items in this guide are based on the Kotlin Style Guide GitHub repository.

Naming

  • All Kotlin source files (.kt) that don’t contain a single top level element (eg a class) use lowercase letters, which can contain underscores: eg name_printer.kt
  • Every top level Kotlin source file that has a single top level element is named after the element: eg HTMLElement
  • Classes/enums/objects use the title case naming scheme (well known abbreviations are permitted) and use singular nouns: eg StringFormatter, NOT StringFormatters
  • Variables/properties use the camel case naming scheme: eg mainActivity
  • Constants use uppercase letters with each word separated by an underscore: eg TXT_FILE_EXT
  • If there are multiple Kotlin source files then all of them must be in a package
  • Each package is named in lowercase letters containing no special characters: eg fpexercises
  • Use of Hungarian Notation for naming is prohibited!
  • Avoid using reserved keywords for names
  • If a defined function has a single function parameter that initialises an object for a DSL then name the parameter init, eg:

```kotlin
fun parentHtmlElement(tagName: String, init: ParentHtmlElement.() -> Unit) =
createParentHtmlElement(tagName, init)
```

Formatting

  • All Kotlin source files use the UTF-8 character encoding
  • All Kotlin code including comments are written using the same human language (eg English)
  • Only soft tabs (tab characters converted to spaces) are used
  • Standard indentation of 4 spaces with each soft tab
  • Every major Kotlin element defined (class/object/enum/function) is separated by a single blank line
  • Single line lambdas/classes/objects/enums have both curly braces on the same line, eg:

```kotlin
class Person(val firstName: String, val lastName: String, val age: Int){}
```

  • Multi line curly brace items have the curly braces on separate lines, eg:

```kotlin
fun printName(name: String) {
println(“ — — — “)
println(“Hello $name”)
println(“ — — — “)
}
```

  • Each separate single line if statement should omit the curly braces, eg:

```kotlin
if(name != null) printName(name)
```

  • If the if/else if/else blocks contain multiple lines then curly braces must be used, eg:

```kotlin
if(age in 0..3) {
println(“Baby”)
processBaby()
} else if(age in 4..12) {
println(“Child”)
processChild()
} else if(age in 13..17) {
println(“Teenager”)
processTeenager()
} else {
println(“Adult”)
processAdult()
}
```

  • Only a single statement is allowed on each line
  • Avoid using semicolons to separate multiple statements
  • If a defined function has a single function as a parameter then position it as the last parameter, eg:

```kotlin
fun buildString(prefix: String, init: StringBuilder.() -> Unit): String {
// …
}
```

  • When using operators in a statement leave other operators before the wrap, eg:

```kotlin
val s = “foo” +
“bar”
```

  • Annotations without arguments can be placed on the same line, eg:

```kotlin
@JsonExclude @JvmField
var x: String
```

  • A defined class that has multiple parameters in the primary constructor should be formatted like the following:

```kotlin
class C(
val a: String,
val b: String,
val c: String
) : SuperType() {
val d: String = “”
}
```

Classes

- Keep every defined class closed (omit the use of the **open** keyword) unless there is a VERY good reason to open up a class to allow inheritance
- When a class extends a class and implements one or more interfaces then position the name of the super class first before the interface names, eg:

```kotlin
class DivElement : HTMLElement(), Serializable {
// …
}
```

  • When modelling data use a Data Class over a Class
  • With a Class prefer composition over classic inheritance
  • Prefer defining Class properties in the primary constructor instead of in the body

Lambdas

  • Use the it keyword to access a parameter for a single argument/single line lambda
  • Always define a single lambda parameter for a single argument lambda that is over multiple lines, eg:

```kotlin
list.filter { it > 10 }.map { element ->
processElement(element)
element * 2
}
```

  • Prefer defining and using a function instead when a lambda uses more than 4 lines and/or is defined/used multiple times
  • Limit lambda nesting to 4 levels
  • Use apply function for object initialisation, eg:

```kotlin
val foo = createBar().apply {
property = value
init()
}

ShareCompat.IntentBuilder.from(this).apply {
setChooserTitle(title)
setType(mimeType)
setText(txt)
}.startChooser()
```

  • Prefer using the apply/run functions over the with function when dealing with a nullable receiver, eg:

```kotlin
getNullable()?.run {
init()
}
```

Update

Kotlin now has its own official Coding Conventions.

--

--

No responses yet