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

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

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

Комментарии (3)


  1. ArchieHabr
    22.09.2022 14:17
    +2

    И есть какой-то значимый выигрыш от потери читаемости? Бинарь будет весить на 1кб меньше? Или может комплироваться будет на 10мс быстрее?

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


    1. PlatinumThinker
      22.09.2022 14:25
      +3

      Выигрыш в устойчивости вашего приложения — если будет строка то вы можете туда запихать что угодно, а это ошибки в рантайме. Плюс если например в вышеупоменутом http поменяют названия методов c "GET" на "get" это потребует от вас каких то дороботок, а используя константы все останется работать


      1. ArchieHabr
        22.09.2022 14:32
        -1

        это все "и ежу понятно" что литералы лучше не использовать., потому что можно опечататься.

        Однако завести свою переменную InternalError компактнее чем вызывать её из либы, как кажется.

        Если обсуждать в рамках приведенных примеров.