Проверка кода:
package bad
import (
"strings"
"strconv"
)
func startWith(in, test string) bool {
if len(test) > len(in) {
return false
}
i := 0
for range test {
if test[i] != in[i] {
return false
}
i++
}
return true
}
func Line(in string) (string, string) {
if len(in) == 0 {
return "", ""
}
i := strings.Index(in, stringEmpty)
if i == -1 {
return in[1:], ""
}
return in[1:i], in[i+1:]
}
func extractFlightLevel(in string) int {
fl, _ := strconv.Atoi(in[1:])
return fl
}Ваш код в целом хорош, но есть несколько мест, где можно сделать его более идеоматичным для Go. Вот некоторые из них:
- Игнорирование ошибок: В функции
extractFlightLevel, вы игнорируете ошибку, возвращаемую функциейstrconv.Atoi. Это может привести к непредсказуемому поведению, если входная строка не может быть преобразована в число. Вместо этого, рекомендуется обрабатывать ошибки.
func extractFlightLevel(in string) (int, error) {
fl, err := strconv.Atoi(in[1:])
if err != nil {
return 0, err
}
return fl, nil
}- Использование ручного цикла для сравнения строк: В функции
startWith, вы используете ручной цикл для сравнения строк. Вместо этого, вы можете использовать встроенную функциюstrings.HasPrefix.
func startWith(in, test string) bool {
return strings.HasPrefix(in, test)
}- Неизвестная переменная: В функции
Line, вы используете переменнуюstringEmpty, которая не определена в представленном коде. Кроме того, пустое значение""вернёт0, а не-1.
i := strings.Index(in, stringEmpty)- Срезы строк: В функции
Line, вы используетеin[1:]для создания среза строки, начинающегося со второго символа. Если это преднамеренное действие, то все в порядке. Однако, если вы хотите вернуть всю строку, когдаi == -1, вам следует использовать простоin, а неin[1:]. Т.к. индекс среза начинается с0, а не с1.
if i == -1 {
return in, ""
}- Требуются тесты: В функции
Lineнеочевидная логика, тесты устраняют возможные ошибки или непредсказуемое поведение. Например:
func Line(in, stringEmpty string) (string, string) {
if len(in) == 0 {
return "", ""
}
if stringEmpty == "" {
return in, ""
}
i := strings.Index(in, stringEmpty)
if i == -1 {
return in, ""
}
return in[:i], in[i+len(stringEmpty):]
}
func TestLine(t *testing.T) {
tests := []struct {
name string
in string
sep string
want1 string
want2 string
}{
{
name: "Empty input",
in: "",
sep: "",
want1: "",
want2: "",
},
{
name: "No separator",
in: "Hello, world!",
sep: "",
want1: "Hello, world!",
want2: "",
},
{
name: "Multi separator",
in: "Hello, world!",
sep: "ll",
want1: "He",
want2: "o, world!",
},
{
name: "Separator at the start",
in: ",Hello, world!",
sep: ",",
want1: "",
want2: "Hello, world!",
},
{
name: "Separator in the middle",
in: "Hello, world!",
sep: ",",
want1: "Hello",
want2: " world!",
},
{
name: "Separator at the end",
in: "Hello, world!",
sep: "!",
want1: "Hello, world",
want2: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got1, got2 := Line(tt.in, tt.sep)
if got1 != tt.want1 || got2 != tt.want2 {
t.Errorf("Line() = (%v, %v), want (%v, %v)", got1, got2, tt.want1, tt.want2)
}
})
}
}Именование переменных и функций - это важная часть написания чистого и понятного кода. В Go есть некоторые общепринятые соглашения и рекомендации по именованию. Вот некоторые из них, которые могут быть применимы к вашему коду:
-
Используйте короткие, описательные имена: В Go обычно рекомендуется использовать короткие имена переменных, особенно для локальных переменных и параметров. Например, вместо
inиtestв функцииstartWithвы можете использовать более описательные имена, такие какstrиprefix. -
Используйте camelCase для имен переменных и функций: В Go обычно используется camelCase для имен переменных и функций. Например,
startWithиextractFlightLevelхорошо соответствуют этому соглашению. -
Используйте имена, которые отражают тип и назначение переменной: Имя переменной должно отражать ее тип и то, что она представляет. Например, в функции
extractFlightLevelимя переменнойflхорошо отражает то, что она представляет уровень полета. -
Используйте глаголы для имен функций: Имена функций обычно начинаются с глагола, отражающего то, что функция делает. Например,
startWithиextractFlightLevelхорошо соответствуют этому соглашению. -
Избегайте сокращений и аббревиатур: Сокращения и аббревиатуры могут затруднить понимание кода. Лучше использовать полные слова, если это возможно.
В целом, ваш код уже хорошо соответствует этим рекомендациям. Однако всегда есть место для улучшения, и надеюсь, что эти советы будут полезны для вас.