代码生成利器 - Go Generate

这篇具有很好参考价值的文章主要介绍了代码生成利器 - Go Generate。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

在Go语言中,go generate​ 命令是一个非常有用的工具,它可以帮助我们自动化地生成代码。本文将详细介绍如何使用 go generate​ 命令,并提供一些示例来说明它的用法。

什么是Generate命令?

go generate​ 命令是一个用于自动化生成Go代码的工具。它可以在Go源文件中的特殊注释中指定命令,然后在运行 go generate​ 命令时自动执行这些命令。这些命令可以用来生成代码、格式化代码、运行测试等等。

在Go 1.4版本中,go generate​ 命令首次发布,它的目的是为了解决Go语言中的一些重复性工作。自从发布以来,它已经成为了一个非常受欢迎的工具,广泛应用于Go语言的开发中。

语法

go generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages]
  • generate 由现有指令描述的运行命令文件。这些命令可以运行任何进程,但目的是创建或更新 Go 源文件
  • Go generate永远不会由 go build、go test 等等。它必须显式运行

注释格式:

在Go源文件中使用 go generate​ 命令需要在源代码中添加特殊注释,格式如下:

其中, command​ 是要执行的命令, arguments​ 是传递给该命令的参数。

//go:generate command argument...

Generate命令的使用示例

例如,假设我们有一个名为 hello.go​ 的源文件,其中包含以下注释:

//go:generate echo "Hello, World!"

当我们在命令行中运行 go generate​ 命令时,它将自动执行上述注释中的命令,并在控制台中输出 “Hello, World!”。

Generate生成顺序

//go:generate echo "top"
package main

import "fmt"

//go:generate echo "middle"
func main() {
    fmt.Println("hello, go generate")
}

//go:generate echo "tail"

$go generate main.go
top
middle
tail

正则匹配生成

go generate还可以通过-run使用正则式去匹配各源文件中go generate指示符中的命令,并仅执行匹配成功的命令:

// 未匹配到任何go generate指示符中的命令
$go generate -x -v -run "protoc" ./...
main.go
subpkg1/subpkg1.go
subpkg2/subpkg2.go

Generate应用场景

生成枚举类型的String方法

这里我们需要安装stringer工具

 go install  golang.org/x/tools/cmd/stringer@latest

假如有如下枚举

type BACnetComfirmedServiceChoice byte

const (
	ServiceConfirmedAcknowledgeAlarm           BACnetComfirmedServiceChoice = 0 //确认报警服务
	ServiceConfirmedComfirmedCOVNotification   BACnetComfirmedServiceChoice = 1 //证实COV通告服务
	ServiceConfirmedComfirmedEventNotification BACnetComfirmedServiceChoice = 2 //证实事件通过服务
}

通常我们会为枚举类型手写String方法,这样在打印上面枚举常量时能输出有意义的内容:

func (d BACnetComfirmedServiceChoice ) String() string {
    switch d {
    case ServiceConfirmedAcknowledgeAlarm           :
        return "确认报警服务"
    case ServiceConfirmedComfirmedCOVNotification   :
        return "证实COV通告服务"
    case ServiceConfirmedComfirmedEventNotification:
        return "证实事件通过服务"
    }

    return "确认报警服务"
}

如果一个项目中枚举常量类型有很多,逐个为其手写String方法费时费力。当枚举常量有变化的时候,手动维护String方法十分烦琐且易错。对于这种情况,使用go generate驱动stringer工具为这些枚举类型自动生成String方法的实现不失为一个较为理想的方案。下面就是利用go generate对上面示例的改造:

//go:generate stringer -type=BACnetComfirmedServiceChoice -linecomment
type BACnetComfirmedServiceChoice byte

const (
	ServiceConfirmedAcknowledgeAlarm           BACnetComfirmedServiceChoice = 0 //确认报警服务
	ServiceConfirmedComfirmedCOVNotification   BACnetComfirmedServiceChoice = 1 //证实COV通告服务
	ServiceConfirmedComfirmedEventNotification BACnetComfirmedServiceChoice = 2 //证实事件通过服务
}

利用generate生成代码如下:

// Code generated by "stringer -type=BACnetComfirmedServiceChoice -linecomment"; DO NOT EDIT.

package generate

import "strconv"

func _() {
	// An "invalid array index" compiler error signifies that the constant values have changed.
	// Re-run the stringer command to generate them again.
	var x [1]struct{}
	_ = x[ServiceConfirmedAcknowledgeAlarm-0]
	_ = x[ServiceConfirmedComfirmedCOVNotification-1]
	_ = x[ServiceConfirmedComfirmedEventNotification-2]
}

const _BACnetComfirmedServiceChoice_name = "确认报警服务证实COV通告服务证实事件通过服务"

var _BACnetComfirmedServiceChoice_index = [...]uint8{0, 18, 39, 63}

func (i BACnetComfirmedServiceChoice) String() string {
	if i >= BACnetComfirmedServiceChoice(len(_BACnetComfirmedServiceChoice_index)-1) {
		return "BACnetComfirmedServiceChoice(" + strconv.FormatInt(int64(i), 10) + ")"
	}
	return _BACnetComfirmedServiceChoice_name[_BACnetComfirmedServiceChoice_index[i]:_BACnetComfirmedServiceChoice_index[i+1]]
}

protobuf

通过generate将protoc预生成指令写在代码中

package main

import (
    "fmt"
    msg "go-generate/protobuf/msg"
)

//go:generate protoc -I ./IDL msg.proto --gofast_out=./msg
func main() {
    var m = msg.Request{
        MsgID:  "xxxx",
        Field1: "field1",
        Field2: []string{"field2-1", "field2-2"},
    }
    fmt.Println(m)
}

ebpf

在cilium/ebpf中使用generate调用其cmd下的bpf2go进行编译

/ $BPF_CLANG and $BPF_CFLAGS are set by the Makefile.
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf xdp.c -- -I../headers

func main() {
	....
}

总结

go generate​ 命令是一个非常有用的工具,它可以帮助我们自动化地生成代码。在本文中,我们介绍了如何在Go源代码中使用 go generate​ 命令,并提供了一些示例来说明它的用法。使用 go generate​ 命令可以提高我们的开发效率,减少我们的重复性工作。

参考资料

  1. 命令 go - Go 编程语言 (google.cn)
  2. Generating code - The Go Programming Language
  3. gostringer 命令 - github.com/sourcegraph/gostringer - go 包
  4. ebpf/main.go at master · cilium/ebpf (github.com)

推荐一个零声学院免费教程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习文章来源地址https://www.toymoban.com/news/detail-424709.html

到了这里,关于代码生成利器 - Go Generate的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • go generate命令简介

    最近在研究kratos的使用,发现在 kratos run 之前会先运行 go generate ./... 命令。 这个命令之前没怎么用过,所以决定学习下该命令的用法。 go generate 是Go语言中的一个命令,用于在Go源代码中执行自定义的命令或脚本,以生成代码或执行其他必要的构建任务。 下面是使用 go gen

    2024年02月13日
    浏览(35)
  • Go开发使用bee工具生成beego框架工程代码、运行web项目以及beego中内置模板函数列表

        GO开发中使用bee工具生成beego框架工程代码,在这之前假定你已经成功安装好了Beego环境搭建和bee工具,Windows下Beego环境搭建和bee工具的安装使用_bee命令 windows-CSDN博客 然后在命令行或者在git bash中进入到GOPATH的src目录,执行bee new 工程名称,来生成一个beego框架工程目录:

    2024年04月29日
    浏览(24)
  • 【go-zero】(1):尝试使用go-zero的工具goctl进行model,controller代码生成,配置数据库,实现FindAll方法,查询数据库全部数据

    本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/128707849 未经博主允许不得转载。 博主CSDN地址是:https://blog.csdn.net/freewebsys 博主掘金地址是:https://juejin.cn/user/585379920479288 博主知乎地址是:https://www.zhihu.com/people/freewebsystem 项目地址: https://go-zero.dev/cn/ go-zero 是一个集

    2023年04月24日
    浏览(31)
  • 如何理解Go言中的Context?

    目前看过除了《go语言程序设计》以外最好的教程:https://www.practical-go-lessons.com 原文:https://www.practical-go-lessons.com/chap-37-context 你将在本章中学到什么? 1.什么是上下文? 2.什么是链表? 3.如何使用上下文包? 涵盖的技术概念 Context derivation Linked list Context key-value pair Cancella

    2024年02月08日
    浏览(32)
  • AIGC for code(AIGC/AI生成代码/生成式AI之代码生成/AI编程工具/自动编程/自动生成代码/智能编程工具/智能编程系统)

    AIGC,Artificial Intelligence Generated Content,人工智能生成内容 AIGC for code,AI生成代码 Copilot是由微软的子公司Github与openAI共同开发的人工智能(AI)驱动的编程助手。它能够直接在你的编辑器中,为你提供代码片段或者整个函数的建议,以帮助你更快地编写和完成代码。这个工具

    2024年02月17日
    浏览(62)
  • AIGC for code(text-to-codeAIGC/AI生成代码/生成式AI之代码生成/AI编程工具/自动编程/自动生成代码/智能编程工具/智能编程系统)

    AIGC,Artificial Intelligence Generated Content,人工智能生成内容 AIGC for code,AI生成代码 Copilot是由微软的子公司Github与openAI共同开发的人工智能(AI)驱动的编程助手。它能够直接在你的编辑器中,为你提供代码片段或者整个函数的建议,以帮助你更快地编写和完成代码。这个工具

    2024年02月15日
    浏览(47)
  • 代码生成二维码

    Zxing Zxing 是一个开源的 Java 二维码扫描和生成库,由美国 Google 公司的一位开发者 Sean Owen 在 2006 年开发并发布,它是用 Java 语言编写的,可以方便地集成到各种应用中。 项目地址为:https://github.com/zxing/zxing 在进行二维码生成前,需要先创建一个 MultiFormatWriter 对象,并使用

    2024年02月03日
    浏览(29)
  • ChatGPT实现代码生成

    就代码生成而言,ChatGPT 是一款卓越的工具,它为开发者提供强大的功能。ChatGPT 可以运用其出色的自然语言处理技术,深入理解和解释开发者的需求,快速生成适合的代码片段。对于那些繁琐的任务或者重复的代码,ChatGPT 能够在瞬间完成,让程序员将更多的时间投入到核心

    2024年02月02日
    浏览(28)
  • 源生成器:根据需要自动生成机械重复代码

    本文概述了利用.NET Compiler Platform(“Roslyn”)SDK 附带的 源生成器 (Source Generator)自动生成机械重复的代码。关于这部分的基础入门知识可以在MSDN [1] 学到。 本文 默认 已经有一个解决方案,包含两个项目。一个是普通C#项目,依赖于另一个源生成器项目。 此处以 Dependenc

    2024年02月01日
    浏览(55)
  • Unity代码生成实例物体

    1、Instantiate(生成的物体,生成位置,旋转角度); 比如: 2、前面可以使用GameObject的变量接收,如果Instantiate生成的是预制体,则GameObject变量具有预制体的一切参数,可利用这一点为预制体的一些参数赋值。 这里的enemyMove是挂接在预制体上的代码,代码需要将player物体传递

    2024年02月13日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包