Skip to content

Latest commit

 

History

History
63 lines (53 loc) · 3.39 KB

best-practices.md

File metadata and controls

63 lines (53 loc) · 3.39 KB

Use A rather than B for simplicity or clarity

A B Note
with(...) run(...) if the receiver is not nullable.
emptyList
emptySet
emptyMap
emptyFlow
listOf
setOf
mapOf
flowOf
buildList
buildSet
buildMap
mutableListOf
mutableSetOf
mutableMapOf
repeat(n) { println(it) } for (i in 0..<n) { println(i) }
Iterable<T>.find(...) Iterable<T>.firstOrNull(...) find is an alias of firstOrNull.
Collection<T>.size
String.length
Collection<T>.count()
String.count()
String.substring(...) String.take(...)
Set<T> List<T> if elements are unique and unordered. Don't overuse List<T>.
SortedSet<T> Set<T> if elements must remain sorted.
SortedMap<T> Map<T> if keys must remain sorted.
Iterable<T>.forEachIndexed { i, x -> ... } Iterable<T>.forEach { ... } if you need to access both indices and elements.
nullableString.orEmpty()
nullableList.orEmpty()
nullableString ?: ""
nullableList ?: emptyList()
CharSequence.lastIndex
List<T>.lastIndex
String.length - 1
List<T>.size - 1
List<Int>.sumBy {...} or List<Int>.sumByDouble {...} List<Int>.map {...}.sum()
(this.)javaClass.simpleName this::class.java.simpleName
Flow.filterNotNull() Flow.flatMapConcat { if (it != null) flowOf(it) else emptyFlow() }

Prefer infix notation

Recommended Not recommended
in
!in
contains
A to B Pair(A, B)

Date and time

Recommended Not recommended
kotlin.time.Duration java.time.Duration
DateTimeFormatter.ISO_LOCAL_DATE DateTimeFormatter.ofPattern("yyyy-MM-dd")
DateTimeFormatter.ISO_LOCAL_TIME DateTimeFormatter.ofPattern("HH:mm:ss")

Use onEach or onEachIndexed when you want to perform a side effect for clarity

For example, the following is better ...

val capitals = listOf('a', 'b', 'c')
        .onEach { println(it) } // a b c
        .map { it.uppercaseChar() }

... than the following.

val capitals = listOf('a', 'b', 'c')
        .map {
            println(it) // a b c
            it.uppercaseChar()
        }

Misc

  • Decompose a pair if possible.
    • Recommended: listOf("apple" to "🍎", "orange" to "🍊").map { it.first + it.second })
    • Not recommended: listOf("apple" to "🍎", "orange" to "🍊").map { (fruit, emoji) -> fruit + emoji }
  • When defining a function, make the parameter types as abstract as possible.
    • e.g. Use a type as left as possible.
      • Iterable > Collection > (Set) > List.
  • Mark a function with suspend if you need to call another suspend function in it, but cannot access CoroutineScope.