Как взломать длинную строку кода в Golang?



Исходя из Python, я не привык видеть строки кода длиннее 80 столбцов.
Поэтому, когда я сталкиваюсь с этим:



err := database.QueryRow("select * from users where user_id=?", id).Scan(&ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email)


Я попытался разбить его на



err := database.QueryRow("select * from users where user_id=?", id) 
.Scan(&ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email)


Но я получаю



 syntax error: unexpected 


Я также попытался просто разорвать линию, нажав enter и поставив точку с запятой в конце:



err := database.QueryRow("select * from users where user_id=?", id) 
.Scan(&ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email);


Но я снова получаю:



syntax error: unexpected .


Итак, мне интересно, каков голангический способ сделать это?

602   4  
go

4 ответов:

Сначала немного фона. Формальная грамматика Go использует точки с запятой ";" как терминаторы во многих производствах, но программы Go могут опустить большинство из них (и они должны иметь более ясный, легко читаемый источник; gofmt также удаляет ненужные точки с запятой).

В спецификации перечислены точные правила. Спецификация: Точка С Запятой:
Формальная грамматика использует точки с запятой"; " как терминаторы в ряде произведений. Программы Go могут опустить большинство этих точек с запятой, используя следующие два правила:
  1. Когда входные данные разбиты на токены, точка с запятой автоматически вставляется в поток токенов сразу после последнего токена строки, если этот токен

  2. Чтобы сложные операторы занимали одну строку, точка с запятой может быть опущена перед закрывающим ") "или"}".

Таким образом, если вы вставляете символ новой строки после скобки ), точка с запятой ; будет вставлена автоматически, и поэтому следующая строка не будет рассматриваться как продолжение предыдущей строки. Вот что произошло в вашем случае, и поэтому следующая строка, начинающаяся с .Scan(&ReadUser.ID,..., даст вам ошибку времени компиляции, так как эта стоящая рядом сама (без предыдущей строки) является ошибкой времени компиляции: syntax error: unexpected .

Таким образом, вы можете прервать свою линию в любой точке, которая не противоречит правилам, перечисленным в пункте 1. выше.

Обычно вы можете разбить свои строки после запятой ,, после открытия скобки, например (, [, {, и после точки ., которая может ссылаться на поле или метод некоторой ценности. Вы также можете прервать свою строку после двоичных операторов (тех, которые требуют 2 операнда), например:

i := 1 +
        2
fmt.Println(i) // Prints 3

Здесь стоит отметить одну вещь: если у вас есть структура, фрагмент или литерал карты, перечисляющий начальные значения, и вы хотите разбить строку после перечисления последнего значения, вы должны поставить обязательную запятую ,, даже если это последнее значение и больше не будет следовать, например:

s := []int {
    1, 2, 3,
    4, 5, 6,  // Note it ends with a comma
}

Это должно соответствовать правилам точки с запятой, а также так, чтобы вы можно переставлять и добавлять новые строки без необходимости заботиться о добавлении / удалении последней запятой; например, вы можете просто поменять местами 2 строки без необходимости удалять и добавлять новую запятую:

s := []int {
    4, 5, 6,
    1, 2, 3,
}

То же самое применяется при перечислении аргументов для вызова функции:

fmt.Println("first",
    "second",
    "third",       // Note it ends with a comma
)

Самый простой способ-это просто оставить оператор (.) в первой строке.

\ линейные продолжения также не рекомендуется использовать во многих руководствах по стилю python, вы можете обернуть все выражение в парены, если вы перемещаетесь вперед и назад между go и python, поскольку этот метод работает в обоих языках.

Это вопрос стиля, но мне нравится:

err := database.QueryRow(
    "select * from users where user_id=?", id,
).Scan(
    &ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email,
)

Как уже упоминалось, это вопрос предпочтения стиля. Я понимаю, что создатели Go предложили стиль, основанный на их опыте, из которого я учусь, но также сохраняю часть своего собственного стиля из моего опыта.

Ниже показано, как бы я это отформатировал: err := database. QueryRow("select * from users where user_id=?", id). Scan( &ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email, )

Comments

    Ничего не найдено.