"go generate" 명령은 컴파일 전에 특정 유형의 코드를 자동으로 생성하는 데 사용되며, 코드가 컴파일되기 전에 소스 코드를 기반으로 코드를 생성할 수 있습니다. "go generate" 명령이 실행되면 현재 패키지와 관련된 소스 코드 파일을 검색하고 "//go:generate"가 포함된 모든 특수 주석을 찾아 특수 주석 다음에 나오는 명령을 추출하여 실행합니다.
이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.
Go 언어는 일련의 강력한 도구를 제공하여 이러한 도구를 유연하게 사용하면 프로젝트 개발이 더 쉬워집니다.
bug start a bug report build compile packages and dependencies clean remove object files and cached files doc show documentation for package or symbol env print Go environment information fix update packages to use new APIs fmt gofmt (reformat) package sources generate generate Go files by processing source get add dependencies to current module and install them install compile and install packages and dependencies list list packages or modules mod module maintenance run compile and run Go program test test packages tool run specified go tool version print Go version vet report likely mistakes in packages
도구의 소스 코드는 $GOPATH/src/cmd/internal에 있습니다. 이 문서에서는 주로 Go 도구 생성에 대해 설명합니다.
go generate 명령은 Go 언어 버전 1.4에 새로 추가된 명령으로, 코드가 컴파일되기 전에 소스 코드를 기반으로 자동으로 코드를 생성하는 데 사용되는 경우가 많습니다. . go generate를 실행하면 현재 패키지와 관련된 소스 코드 파일을 스캔하고 "//go:generate"가 포함된 모든 주석문을 찾아 주석 뒤의 명령을 추출하여 실행하면 해당 명령이 실행 가능한 프로그램이 됩니다. 이 프로세스는 쉘 스크립트를 호출하고 실행하는 것과 유사합니다.
//go:generate command argument...
$ go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
package mainimport "fmt"//go:generate echo GoGoGo!//go:generate go run main.go//go:generate echo $GOARCH $GOOS $GOFILE $GOLINE $GOPACKAGEfunc main() { fmt.Println("go rum main.go!")}
go generate 명령 실행
$ go generate GoGoGo!go rum main.go!amd64 darwin main.go 7 main
위의 생성에 대한 간략한 소개를 읽은 후 독자들은 느끼지 못할 수도 있습니다. 그 도구의 강력한 기능인 Xiaocai Knife는 이 도구의 고전적인 응용 시나리오를 제공합니다. 즉, 열거 상수에 대한 문자열 메서드를 구현합니다.
정수 상수 집합에 대해 String() 메서드를 자동으로 작성할 수 있는 또 다른 공식 도구인 stringer를 여기서 언급해야 합니다. stringer는 공식 Go 릴리스의 도구 세트에 포함되어 있지 않으므로 직접 설치하고 다음 명령을 실행해야 합니다.
go get golang.org/x/tools/cmd/stringer
다음은 스트링거 문서에서 인용한 예입니다. 코드는 다음과 같으며 다양한 Pill 유형의 정수 상수 집합을 정의합니다.
package painkillertype Pill intconst ( Placebo Pill = iota Aspirin Ibuprofen Paracetamol Acetaminophen = Paracetamol)
디버깅이나 다른 이유로 인해 우리는 이러한 상수를 인쇄하려고 합니다. 이는 Pill에 서명이 있는 메서드가 있다는 의미입니다.
func (p Pill) String() string
이를 달성하는 방법은 매우 간단합니다.
func (p Pill) String() string { switch p { case Placebo: return "Placebo" case Aspirin: return "Aspirin" case Ibuprofen: return "Ibuprofen" case Paracetamol: // == Acetaminophen return "Paracetamol" } return fmt.Sprintf("Pill(%d)", p)}
알약 목록에 일련의 약물 이름을 추가하면 약물 이름이 추가되거나 수정될 때마다 해당 서명 기능도 변경되어야 한다고 상상해 보세요. 번거롭고 놓치거나 잘못될 가능성이 크지 않나요? 이때 go generate + stringer 솔루션을 통해 이 문제를 해결할 수 있습니다. 매우 간단합니다. Pill을 정의하는 코드에 주석문을 추가하기만 하면 됩니다.
//go:generate stringer -type=Pill
위 명령은 Pill 유형에 대한 String 메서드를 생성하기 위해 stringer 도구를 실행하는 것을 의미하며, 기본적으로 pill_string.go 파일에 출력됩니다.
$ go generate $ cat pill_string.go // Code generated by stringer -type Pill pill.go; DO NOT EDIT. package painkillerimport "fmt"const _Pill_name = "PlaceboAspirinIbuprofenParacetamol"var _Pill_index = [...]uint8{0, 7, 14, 23, 34}func (i Pill) String() string { if i = Pill(len(_Pill_index)) { return fmt.Sprintf("Pill(%d)", i) } return _Pill_name[_Pill_index[i]:_Pill_index[i+1]]}
이렇게 하면 Pill 유형을 수정할 때마다 다음 명령문을 실행하기만 하면 됩니다.
$ go generate
물론, 이것이 번거롭다고 생각하거나 생성 문 실행을 잊어버릴까 봐 걱정된다면요. 그런 다음 Makefile에 go generate 문을 작성하고 go build 명령 앞에 배치하여 코드 생성 및 컴파일을 자동화할 수 있습니다.
Go 소스 코드 문서에서 go generate+stringer 솔루션은 열거형 상수에 대한 String 메서드를 구현하는 데 널리 사용된다는 점을 언급할 가치가 있습니다. Xiaocai Knife의 기본 Go 1.14.1 소스 코드에는 다음과 같이 총 23가지 용도가 있습니다.
이 글에서는 generate가 무엇인지, 무엇을 할 수 있는지를 주로 소개합니다. 내부 구현 로직을 깊이 이해하고 싶다면 Go에서 코드를 생성하는 자세한 과정을 살펴보세요. 정렬 패키지 genzfunc.go 아래로 전달되는 것과 같은 소스 코드는 zfuncversion.go의 생성을 구현합니다. Go 소스 코드 보물창고에서는 유사한 구현 로직을 많이 찾을 수 있습니다. 다음을 참조하세요.
추상 구문 트리 정의를 위한 go/ast, 추상 구문 트리 구문 분석을 위한 go/parser, 코드 형식 구문 분석을 위한 go/format, Go 어휘 태그를 위한 go/token 등 Go 컴파일러에서 제공하는 라이브러리를 활용합니다. . 소스 파일을 구문 분석하고 기존 템플릿에 따라 새 코드를 생성합니다. 이 프로세스는 템플릿을 사용하여 웹 서비스에서 HTML 파일을 생성하는 것과 유사합니다.
【관련 추천: Go 비디오 튜토리얼, 프로그래밍 교육】
위 내용은 go generate 명령의 기능은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!