All Projects → RedMadRobot → kotlin-style-guide

RedMadRobot / kotlin-style-guide

Licence: CC-BY-SA-4.0 license
red_mad_robot Kotlin Style Guide

Projects that are alternatives of or similar to kotlin-style-guide

Elements Of Python Style
Goes beyond PEP8 to discuss what makes Python code feel great. A Strunk & White for Python.
Stars: ✭ 3,308 (+3791.76%)
Mutual labels:  styleguide, style-guide, codestyle
Typescript Guidelines
The TypeScript Guidebook
Stars: ✭ 104 (+22.35%)
Mutual labels:  styleguide, style-guide
Javascript
JavaScript Style Guide
Stars: ✭ 117,286 (+137883.53%)
Mutual labels:  styleguide, style-guide
Nodebestpractices
✅ The Node.js best practices list (December 2021)
Stars: ✭ 72,734 (+85469.41%)
Mutual labels:  styleguide, style-guide
Styleguide Generators
An overview of automatic living styleguide generators
Stars: ✭ 1,902 (+2137.65%)
Mutual labels:  styleguide, style-guide
Flake8
The official GitHub mirror of https://gitlab.com/pycqa/flake8
Stars: ✭ 1,112 (+1208.24%)
Mutual labels:  styleguide, style-guide
Sscss
Light Sass lib for managing your font-size, margin, padding, and position values across breakpoints.
Stars: ✭ 119 (+40%)
Mutual labels:  styleguide, style-guide
Livingstyleguide
Easily create front-end style guides with Markdown and Sass/SCSS.
Stars: ✭ 874 (+928.24%)
Mutual labels:  styleguide, style-guide
Vue Styleguide Generator
React inspired style guide generator for Vue.js
Stars: ✭ 123 (+44.71%)
Mutual labels:  styleguide, style-guide
Javascript Style Guide
Airbnb JavaScript 스타일 가이드
Stars: ✭ 132 (+55.29%)
Mutual labels:  styleguide, style-guide
Frontend Nanodegree Styleguide Zh
优达学城(Udacity)前端样式指南
Stars: ✭ 188 (+121.18%)
Mutual labels:  styleguide, style-guide
Livingcss
Parse comments in your CSS to generate a living style guide using Markdown, Handlebars, Polymer, and Prism syntax highlighter.
Stars: ✭ 237 (+178.82%)
Mutual labels:  styleguide, style-guide
Axiom React
Axiom - Brandwatch design system and React pattern library
Stars: ✭ 41 (-51.76%)
Mutual labels:  styleguide, style-guide
Swift
Airbnb's Swift Style Guide.
Stars: ✭ 1,165 (+1270.59%)
Mutual labels:  styleguide, style-guide
React Styleguide
ReactJS style guide for component-based projects.
Stars: ✭ 14 (-83.53%)
Mutual labels:  styleguide, style-guide
Catalog
Create living style guides using Markdown or React
Stars: ✭ 1,527 (+1696.47%)
Mutual labels:  styleguide, style-guide
Ue4 Style Guide
An attempt to make Unreal Engine 4 projects more consistent
Stars: ✭ 2,656 (+3024.71%)
Mutual labels:  styleguide, style-guide
Front End Style Guide
驴妈妈H5开发规范
Stars: ✭ 16 (-81.18%)
Mutual labels:  styleguide, style-guide
Styleguide Git Commit Message
/sBin/StyleGuide/Git/CommitMessage
Stars: ✭ 934 (+998.82%)
Mutual labels:  styleguide, style-guide
Android Kotlin Style Guide
Kotlin style guide of FRESH LIVE since April, 2015.
Stars: ✭ 121 (+42.35%)
Mutual labels:  styleguide, style-guide

Kotlin Code Style

В репозитории приведен набор соглашений по оформлению кода на языке Kotlin.

Этот список правил расширяет предложенные Google и командой разработки Kotlin гайды и пересматривает в них некоторые неоднозначные моменты.

Длина строки

  • Рекомендуемая длина строки: 100 символов.
  • Максимальная длина строки: 120 символов.

Правила именования

  • Пакеты именуются одним словом в стиле lowercase. Если необходимо использовать несколько слов, то просто склеиваем их вместе.

Форматирование выражений

  • При переносе на новую строку цепочки вызова методов символ . или оператор ?. переносятся на следующую строку, property при этом разрешается оставлять на одной строке:
val collectionItems = source.collectionItems
    ?.dropLast(10)
    ?.sortedBy { it.progress }
  • Элвис оператор ?: в многострочном выражении также переносится на новую строку:
val throwableMessage: String = throwable?.message
    ?: DEFAULT_ERROR_MESSAGE

throwable.message?.let { showError(it) }
    ?: showError(DEFAULT_ERROR_MESSAGE)
  • Если перед элвис оператором ?: многострочная лямбда, желательно перенести также и лямбду:
// Good
throwable.message
    ?.let { message ->
        ...
        showError(message)
    }
    ?: showError(DEFAULT_ERROR_MESSAGE)
    
// Not recommended
throwable.message?.let { message ->
    ...
    showError(message)
}
    ?: showError(DEFAULT_ERROR_MESSAGE)
  • При описании переменной с делегатом, не помещающимися на одной строке, оставлять описание с открывающейся фигурной скобкой на одной строке, перенося остальное выражение на следующую строку:
private val promoItem: MarkPromoItem by lazy {
    extractNotNull(BUNDLE_FEED_UNIT_KEY) as MarkPromoItem
}

Функции

Функции с одним выражением

  • Позволительно использовать функцию с одним выражением только в том случае, если она помещается в одну строку.

Именованные аргументы

  • Если по контексту не понятно назначение аргумента, то следует сделать его именованным.
runOperation(
    method = operation::run,
    consumer,
    errorHandler,
    tag,
    cacheSize = 3,
    cacheMode
)
calculateSquare(x = 6, y = 19)
getCurrentUser(skipCache = false)
setProgressBarVisible(true)
  • Если именованные аргументы не помещаются на одной строке, то следует переносить каждый аргумент на новую строку (как в примере выше).
  • Именуем все лямбды, принимаемые функцией в качестве аргументов (кроме случаев когда лямбда вынесена за круглые скобки), чтобы во время чтения кода было понятно назначение и ответственность каждой лямбды.
editText.addTextChangedListener(
    onTextChanged = { text, _, _, _ -> 
        viewModel.onTextChanged(text?.toString())
    },
    afterTextChanged = { text ->
        viewModel.onAfterTextChanged(text?.toString())
    }
)
  • Полезно именовать аргументы одинаковых типов, чтобы случайно не перепутать их местами.
val startDate: Date = ..
val endDate: Date = ..
compareDates(startDate = startDate, endDate = endDate)
  • Полезно именовать аргумент при передаче null.
setAdditionalArguments(arguments = null)

Вызов переменной функционального типа

  • Всегда использовать полный вариант с написанием invoke у переменной вместо использования сокращенного варианта:
fun runAndCall(expression: () -> Unit): Result {
    val result = run()
    
    //Bad
    expression()
    //Good
    expression.invoke()
    
    return result
}

Форматирование лямбда-выражений

  • По возможности передавать метод по ссылке:
viewPager.adapter = QuestAdapter(quest, onQuestClickListener = ::onQuestClicked)
  • При написании лямбда-выражения более чем в одну строку всегда использовать именованный аргумент, вместо it:
viewPager.adapter = QuestAdapter(
    quest, 
    onQuestClickListener = { quest ->
        Log.d(..)
        viewModel.onQuestClicked(quest)
    }
)
  • Неиспользуемые параметры лямбда-выражений всегда заменять символом _.

Классы

  • Если описание класса не помещается в одну строку, и класс реализует несколько интерфейсов, то применять стандартные правила переноса, т.е. делать перенос только в случае, когда описание не помещается на одну строку, при этом продолжать перечисление интерфейсов на следующей строке.
class MyFavouriteVeryLongClassHolder : MyLongHolder<MyFavouriteVeryLongClass>(), SomeOtherInterface, AndAnotherOne,
    OneMoreVeryLongInteface, OneMore{

    fun foo() { /*...*/ }
}

Структура класса

  1. Поля: abstract, override, public, internal, protected, private
  2. Блок инициализации: init, конструкторы
  3. Абстрактные методы
  4. Переопределенные методы родительского класса (желательно в порядке их следования в родительском классе)
  5. Реализации методов интерфейсов (желательно в порядке добавления интерфейсов в класс и следования методов в каждом интерфейсе)
  6. Методы класса (в логическом порядке. Например, метод располагается после того, в котором впервые упомянут). Можно перемешивать с методами из пунктов 3, 4, 5.
  7. inner классы
  8. companion object

Аннотации

  • Аннотации располагаются над описанием класса/поля/метода, к которому они применяются.
  • Если к классу/полю/методу применяется несколько аннотаций, размещать каждую аннотацию с новой строки:
@JsonValue
@JvmField
var promoItem: PromoItem? = null
  • Аннотации к аргументам в конструкторе класса или объявлении функции можно писать на той же строке, что и соответствующий аргумент.
    При этом если аннотаций к одному аргументу несколько, то все аннотации пишутся с новой строки, и соответствующий аргумент отделяется от других сверху и снизу пустыми строками.
data class UserInfo (
    @SerializedName("firstName") val firstName: String? = null,
    @SerializedName("secondName") val secondName: String? = null
)

@Entity(tableName = "users")
data class UserInfo (
    @PrimaryKey val id: Int,
    
    @SerializedName("firstName") 
    @ColumnInfo(name = "firstName") 
    val firstName: String? = null,
    
    @SerializedName("secondName") 
    @ColumnInfo(name = "secondName") 
    val secondName: String? = null
)

Использование условных операторов

  • Не обрамлять if выражения в фигурные скобки только если условный оператор if помещается в одну строку.
    По возможности использовать условные операторы, как выражение:
return if (condition) foo() else bar()
  • В операторе when ветки, состоящие более чем из одной строки, обрамлять фигурными скобками и отделять от других case-веток пустыми строками сверху и снизу.
when (feed.type) {
    FeedType.PERSONAL -> startPersonalFeedScreen()
    
    FeedType.SUM -> {
        showSumLayout()
        hideProgressBar()
    }
    
    FeedType.CARD -> startCardFeedScreen()
    else -> showError() 
}

Template header

  • Не использовать Template Header для классов (касается авторства и даты создания файла).

Частые ошибки

Вызов toString() у nullable объектов

  • В первом примере получится строчка "null", это плохо. Необходимо сделать так, чтобы в таком случае возвращалась пустая строка ""
binding.authInputPassword.addTextChangeListener { editable: Editable? ->
    // Bad
    viewModel.onPasswordChanged(editable.toString())
    
    // Good
    viewModel.onPasswordChanged(editable?.toString().orEmpty())
}

Использование orEmpty() вместо ?:

  • Для коллекций и строк использовать orEmpty().
// Bad
nullableString ?: ""
nullableObject?.toString() ?: ""
someList ?: emptyList()

// Good
nullableString.orEmpty()
nullableObject?.toString().orEmpty()
someList.orEmpty()

Проверка nullable boolean

  • При проверке nullable boolean вместо добавления ?: false в условии явно проверять boolean == true
    Это одна из общепринятных идиом Kotlin.
// Bad
val b: Boolean? = ...
if (boolean ?: false) {
    ...
} else {
    // `b` is false or null
}

// Good
val b: Boolean? = ...
if (b == true) {
    ...
} else {
    // `b` is false or null
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].