Skip to content

Latest commit

 

History

History
362 lines (239 loc) · 8.1 KB

File metadata and controls

362 lines (239 loc) · 8.1 KB

Inspiration

This style-guide is somewhat of a mash-up between the existing Kotlin language style guides, and a tutorial-readability focused Swift style-guide. The language guidance is drawn from:

Table of Contents

Nomenclature

On the whole, naming should follow Java standards, as Kotlin is a JVM-compatible language.

Packages

Package names are similar to Java: all lower-case, multiple words concatenated together, without hypens or underscores:

BAD:

com.Sysdata.funky_widget

GOOD:

com.sysdata.funkywidget

Classes & Interfaces

Written in UpperCamelCase. For example RadialSlider.

Methods

Written in lowerCamelCase. For example setValue.

Fields

Generally, written in lowerCamelCase. Fields should not be named with Hungarian notation, as Hungarian notation is erroneously thought to be recommended by Google.

Example field names:

class MyClass {
  var publicField: Int = 0
  val person = Person()
  private var privateField: Int?
}

Constant values in the companion object should be written in uppercase, with an underscore separating words:

companion object {
  const val THE_ANSWER = 42
}

Variables & Parameters

Written in lowerCamelCase.

Single character values must be avoided, except for temporary looping variables.

Misc

In code, acronyms should be treated as words. For example:

BAD:

XMLHTTPRequest
URL: String? 
findPostByID

GOOD:

XmlHttpRequest
url: String
findPostById

Declarations

Visibility Modifiers

Only include visibility modifiers if you need something other than the default of public.

BAD:

public val wideOpenProperty = 1
private val myOwnPrivateProperty = "private"

GOOD:*

val wideOpenProperty = 1
private val myOwnPrivateProperty = "private"

Access Level Modifiers

Access level modifiers should be explicitly defined for classes, methods and member variables.

Fields & Variables

Prefer single declaration per line.

GOOD:

username: String
twitterHandle: String

Classes

Exactly one class per source file, although inner classes are encouraged where scoping appropriate.

Data Type Objects

Prefer data classes for simple data holding objects.

BAD:

class Person(val name: String) {
  override fun toString() : String {
    return "Person(name=$name)"
  }
}

GOOD:

data class Person(val name: String)

Enum Classes

Enum classes should be avoided where possible, due to a large memory overhead. Static constants are preferred. See http://developer.android.com/training/articles/memory.html#Overhead for further details.

Enum classes without methods may be formatted without line-breaks, as follows:

private enum CompassDirection { EAST, NORTH, WEST, SOUTH }

Spacing

Spacing is especially important in Sysdata code, as code needs to be easily readable as part of the tutorial.

Indentation

Indentation is using spaces - never tabs.

Line Length

Lines should be no longer than 100 characters long.

Vertical Spacing

There should be exactly one blank line between methods to aid in visual clarity and organization. Whitespace within methods should separate functionality, but having too many sections in a method often means you should refactor into several methods.

Semicolons

Semicolons are dead to us should be avoided wherever possible in Kotlin.

BAD:

val horseGiftedByTrojans = true;
if (horseGiftedByTrojans) {
  bringHorseIntoWalledCity();
}

GOOD:

val horseGiftedByTrojans = true
if (horseGiftedByTrojans) {
  bringHorseIntoWalledCity()
}

Getters & Setters

Unlike Java, direct access to fields in Kotlin is preferred.

If custom getters and setters are required, they should be declared following Kotlin conventions rather than as separate methods.

Brace Style

Only trailing closing-braces are awarded their own line. All others appear the same line as preceding code:

BAD:

class MyClass
{
  fun doSomething()
  {
    if (someTest)
    {
      // ...
    }
    else
    {
      // ...
    }
  }
}

GOOD:

class MyClass {
  fun doSomething() {
    if (someTest) {
      // ...
    } else {
      // ...
    }
  }
}

Conditional statements are always required to be enclosed with braces, irrespective of the number of lines required.

BAD:

if (someTest)
  doSomething()
if (someTest) doSomethingElse()

GOOD:

if (someTest) {
  doSomething()
}

When Statements

Unlike switch statements in Java, when statements do not fall through. Separate cases using commas if they should be handled the same way. Always include the else case.

BAD:

when (anInput) {
  1 -> doSomethingForCaseOne()
  2 -> doSomethingForCaseOneOrTwo()
  3 -> doSomethingForCaseThree()
}

GOOD:

when (anInput) {
  1, 2 -> doSomethingForCaseOneOrTwo()
  3 -> doSomethingForCaseThree()
  else -> println("No case satisfied")
}

Types

Always use Kotlin's native types when available.

Type Inference

Type inference should be preferred where possible to explicitly declared types.

BAD:

val something: MyType = MyType()
val meaningOfLife: Int = 42

GOOD:

val something = MyType()
val meaningOfLife = 42

Constants vs. Variables

Constants are defined using the val keyword, and variables with the var keyword. Always use val instead of var if the value of the variable will not change.

Tip: A good technique is to define everything using val and only change it to var if the compiler complains!

Nullable Types

Declare variables and function return types as nullable with ? where a null value is acceptable.

Use implicitly unwrapped types declared with !! only for instance variables that you know will be initialized before use, such as subviews that will be set up in onCreate for an Activity or onCreateView for a Fragment.

When naming nullable variables and parameters, avoid naming them like nullableString or maybeView since their nullability is already in the type declaration.

When accessing a nullable value, use the safe call operator if the value is only accessed once or if there are many nullables in the chain:

editText?.setText("foo")

License

Copyright (C) 2019 Sysdata, S.p.a.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.