Go-разработчики часто пишут свои собственные переменные или константы, а затем используют их в коде, который обращается к стандартной библиотеке. Поэтому наш Go-разработчик Саша Мелентьев создал линтер usestdlibvars, который определяет, можно ли повторно использовать переменные или константы из стандартной библиотеки, вместо того чтобы создавать собственные.
Например, вы создаете запрос. Он должен использовать какой-то метод, например, getpost, в этом случае многие разработчики так и пишут — get. Но вместо этого вы можете использовать константу из стандартной библиотеки. Вам не придётся писать лишний код, линтер сэкономит ваше время.
К примеру, вместо http.NewRequest("GET", "", nil)
можете использовать http.NewRequest(http.MethodGet, "", nil)
— линтер это подсветит.
Важно то, что в стандартной библиотеке много различных переменных, которые можно использовать повторно, но они не всегда подходят. Согласно стандарту, в наш линтер включены только две опции (например, проверка, связанная с внутренней библиотекой http), чтобы не было ложных срабатываний.
Название линтера, UseStdLibVars, по сути, является призывом к действию «Используйте переменные стандартных библиотек». Линтер уже включен в golangci-lint.
Установка
go install github.com/sashamelentyev/usestdlibvars@latest
Использование
$ usestdlibvars -h
usestdlibvars: A linter that detect the possibility to use variables/constants from the Go standard library.
Usage: usestdlibvars [-flag] [package]
Flags:
-V print version and exit
-all
no effect (deprecated)
-c int
display offending line with this many lines of context (default -1)
-constant-kind
suggest the use of constant.Kind.String()
-cpuprofile string
write CPU profile to this file
-crypto-hash
suggest the use of crypto.Hash.String()
-debug string
debug flags, any subset of "fpstv"
-fix
apply all suggested fixes
-flags
print analyzer flags in JSON
-http-method
suggest the use of http.MethodXX (default true)
-http-status-code
suggest the use of http.StatusXX (default true)
-json
emit JSON output
-memprofile string
write memory profile to this file
-os-dev-null
suggest the use of os.DevNull
-rpc-default-path
suggest the use of rpc.DefaultXXPath
-source
no effect (deprecated)
-sql-isolation-level
suggest the use of sql.LevelXX.String()
-tags string
no effect (deprecated)
-test
indicates whether test files should be analyzed, too (default true)
-time-layout
suggest the use of time.Layout
-time-month
suggest the use of time.Month.String()
-time-weekday
suggest the use of time.Weekday.String()
-tls-signature-scheme
suggest the use of tls.SignatureScheme.String()
-trace string
write trace log to this file
-v no effect (deprecated)
Примеры
package response
import (
"bytes"
"encoding/json"
"net/http"
)
// JSON marshals v to JSON, automatically escaping HTML,
// setting the Content-Type header as "application/json; charset=utf-8",
// sends an HTTP response header with the provided statusCode and
// writes the marshaled v as bytes to the connection as part of an HTTP reply.
func JSON(w http.ResponseWriter, statusCode int, v any) {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetEscapeHTML(true)
if err := enc.Encode(v); err != nil {
http.Error(w, err.Error(), 500)
return
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(statusCode)
if _, err := w.Write(buf.Bytes()); err != nil {
http.Error(w, err.Error(), 500)
return
}
}
usestdlibvars ./...
response.go:18:30: "500" can be replaced by http.StatusInternalServerError
response.go:24:30: "500" can be replaced by http.StatusInternalServerError
Планы на будущее
Мы будем отслеживать изменения, происходящие в языке. Если появятся новые константы, которые можно использовать в каких-то определенных случаях, мы дополним функциональные возможности линтера. Вы также можете вносить свой вклад и присылать нам пул-реквесты.
ArchieHabr
И есть какой-то значимый выигрыш от потери читаемости? Бинарь будет весить на 1кб меньше? Или может комплироваться будет на 10мс быстрее?
Это все, конечно, сарказм, но я действительно не понимаю в чем выигрыш.
PlatinumThinker
Выигрыш в устойчивости вашего приложения — если будет строка то вы можете туда запихать что угодно, а это ошибки в рантайме. Плюс если например в вышеупоменутом http поменяют названия методов c "GET" на "get" это потребует от вас каких то дороботок, а используя константы все останется работать
ArchieHabr
это все "и ежу понятно" что литералы лучше не использовать., потому что можно опечататься.
Однако завести свою переменную InternalError компактнее чем вызывать её из либы, как кажется.
Если обсуждать в рамках приведенных примеров.