Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Оформление кода

Перечисленные рекомендации не проверяются компилятором, поэтому являются только советами, которые позволяет создавать пригодный и привычный для чтения код.

Стиль записи нескольких слов слитно без пробелов, при котором каждое следующее слово внутри пишется с заглавной буквы, будет далее называться camel case.

Именование

Имена пакетов определяются как измененная запись некоторого url (см. соответствующий раздел). Но обычной практикой является использование только строчных букв с разделением слов при помощи подчёркивания _ или вовсе без разделителя: com/teacode/html, com/teacode/xmlstream, libretto/jvm_jar/websocket, libretto/jvm_jar/nimbus_jose_jwt - в том числе для совместимости с файловыми системами, которые не являются чувствительными к регистру.

Имена структур и трейтов с заглавной буквы и в camel case, главное слово - это существительное (чаще в единственном, но возможно и множественном числе) либо иногда прилагательное (причастие прошедшего времени): Person, TypeInfo, LinkedList, RemovedNumbers, Pinned.

Имя поля (структуры) со строчной буквы и в camel case, главное слово - это существительное (в единственном или множественном числе) либо прилагательное (причастие прошедшего времени): name, parents, sorted, hiddenFiles

Имена методов (обозначающих действие) со строчной буквы и в camel case, главное слово - это глагол: print, removeFromList.

Но имена методов, которые используют new-выражение без указания имени трейта (определение трейта “по месту”), должны выбираться по принципу имён структур и трейтов, а не по принципу обычных методов.

В некоторых случаях глагол можно опускать в имени метода, если используется предлоги, которые позволяют интуитивно понять происходящее действие (to, from и т.п.).

Имена методов, похожих по поведению на поля, определяются аналогично именам полей.

Если метод не имеет параметров и не имеет побочных эффектов, то используется вариант без скобок (чаще всего действие похоже на вычислимое поле): title.

Если метод не имеет параметров, но имеет побочные эффекты, то используется вариант с пустыми скобами: println().

todo (устарело): В чистом виде setter/getter отсутствуют и нет рекомендаций по использованию глаголов set или get для имен методов. Имя метода получения значения допустимо оформлять как имя поля. Метод изменения допустимо оформлять с использованием имени поля, но с параметром (параметрами).

Имена переменных (в том числе as и case-переменных) и параметров со строчной буквы и в camel case, чаще всего главное слово - это существительное или буква (в очевидных случаях).

Префиксы как часть имени

Интересным направлением стиля оформления является использование префиксов (при импорт-подключении пакетов) как смысловой части имени сущности.

Например, есть сущность Node (узел), который используется в разных пакетах. При возможном частом одновременном использовании этих пакетов можно использовать более сложные имена: в одном пакете это, например, будет SourceNode, в другом пакете - TreeNode.

Но можно часть сложного имени перенести в имя пакета, одновременно используя простое имя Node. Например, Node в пакете org/example/source и тоже Node в пакете org/example/tree. Тогда при использовании префиксного имени с импортом по умолчанию будут доступны имена source/Node и tree/Node.

Имена файлов и кодировка

При оформлении библиотек и веб-приложений нет требований к именам файлов и каталогов, только необходимо использовать разрешение .ltt для исходных текстов на Libretto, сами тексты должны быть в UTF-8 кодировке (без BOM).

Но рекомендуется использовать понятную внутреннюю организацию: разделять части пакета по разным файлам, подпакеты размещать в подкаталогах. Имена файлов давать строчными буквами (на случай использования файловой системы без чувствительности к регистру символов), в качестве разделителя слов в имени использовать _ или не использовать разделитель вообще.

Пробелы, переносы строк

Используются отступы, состоящие из двух пробелов, использовать символ табуляции в явном виде не рекомендуется.

Если блок с фигурными скобами записывается в несколько строк, то открывающая скобка { ставится в конце строки, затем идёт тело блока с дополнительным отступом, а закрывающая скобка } ставится следующей строкой со соответствующим отступом:

def test(v: Unit?) = {
  if (v) {
    println("unit")
  }
  else {
    println("()")
  }
}

Прочие особенности синтаксиса

Не рекомендуется использовать бесскобочный способ записи вызова метода (в первую очередь при помощи :) в сложных конструкциях. Нужно учитывать приоритеты, которые могут отличаться от ожидаемых. Например, a(b: c, d) работает как a(b(c, d)) а не как a(b(c), d).

Пример:

def b(p0: String) = "b("+p0+")"
def b(p0: String, p1: String) = "b("+p0+", "+p1+")"

def a(p0: String) = "a("+p0+")"
def a(p0: String, p1: String) = "a("+p0+","+p1+")"

def main = {
  println: a(b: "1", "2")
  println: a((b: "1", "2"))
  println: a((b: "1"), "2")
}

Выдает:

a(b(1, 2))
a(b(1, 2))
a(b(1),2)

Конструкции с case могут показаться более громоздкими, но часто они даёт лучшую читабельность кода.