Главная / Блог / Usestdlibvars

Используем переменные из стандартной библиотеки Go с помощью свободного линтера

September 2022

Разработчики на языке 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

Планы на будущее

Мы будем отслеживать изменения, происходящие в языке. Если появятся новые константы, которые можно использовать в каких-то определенных случаях, мы дополним функциональные возможности линтера. Вы также можете вносить свой вклад и присылать нам пул-реквесты.

Если вы хотите узнать, как можно использовать решения с открытым исходным кодом в вашем проекте, или вам требуется помощь в разработке проекта с нуля, отправьте нам сообщение через форму ниже. Мы свяжемся с вами и обсудим все детали сотрудничества при разработке вашего проекта.

Линтеры не только помогают избежать уязвимостей или снижения производительности, но и содействуют сохранению единого стиля кодовой базы. Используйте линтеры!
Саша Мелентьев
Go-разработчик, Evrone
Будем на связи
Прикрепить файл
Максимальный размер файла: 2 МБ.
Допустимые типы файлов: jpg jpeg png txt rtf pdf doc docx ppt pptx.