cobra是一个提供简单接口来创建强大的现代CLI界面的库类似git git tools,cobra也是一个应用程序,它会生成你的应用程序的脚手架来快速开发基于cobra的应用程序
cobra提供:
cobra建立在命令、参数、标志的结构之上
commands代表动作,args是事物,flags是动作的修饰符
最好的应用程序在使用时读起来就像句子,所以呢,用户直观地知道如何与它们交互
模式如下:APPNAME VERB NOUN --ADJECTIVE. or APPNAME COMMAND ARG --FLAG(APPNAME 动词 名词 形容词 或者 APPNAME 命令 参数 标志)
一些真实世界的好例子可以更好地说明这一点
kubectl 命令更能体现APPNAME 动词 名词 形容词
如下的例子,server 是command,port是flag
这个命令中,我们告诉git 克隆url
命令是应用程序的中心点,应用程序支持的每一个交互都包含在一个命令中,命令可以有子命令,也可以运行操作
在上面的例子中,server是命令
更多关于cobra.Command
flag是一种修改命令行为的方式,cobra支持完全兼容POSIX标志,也支持go flag package,cobra可以定义到子命令上的标志,也可以仅对该命令可用的标志
在上面的命令中,port是标志
标志的功能由 pflag library 提供,pflag library是flag标准库的一个分支,在添加POSIX兼容性的同时维护相同的接口.
使用cobra很简单,首先,使用go get按照最新版本的库,这个命令会安装cobra可执行程序以及库和依赖项
下一步,引入cobra到应用程序中
虽然欢迎您提供自己的组织,但通常基于Cobra的应用程序将遵循以下组织结构:
在Cobra应用程序中,main.go文件通常非常简单.它有一个目的:初始化Cobra.
使用cobra生成器
cobra提供了程序用来创建你的应用程序然后添加你想添加的命令,这是将cobra引入应用程序最简单的方式
这儿 你可以发现关于cobra的更多信息
要手动实现cobra,需要创建一个main.go 和rootCmd文件,可以根据需要提供其他命令
Cobra不需要任何特殊的构造器.只需创建命令.
理想情况下,您可以将其放在app/cmd/root.go中:
在init()函数中定义标志和处理配置
例子如下,cmd/root.go:
创建main.go
使用root命令,您需要让主函数执行它.为清楚起见,Execute应该在根目录下运行,尽管它可以在任何命令上调用.
可以定义其他命令,通常每个命令在cmd/目录中都有自己的文件.
如果要创建版本命令,可以创建cmd/version.go并用以下内容填充它:
如果希望将错误返回给命令的调用者,可以使用RunE.
然后可以在execute函数调用中捕获错误.
标志提供修饰符来控制操作命令的操作方式.
由于标志是在不同的位置定义和使用的,所以呢我们需要在外部定义一个具有正确作用域的变量来分配要使用的标志.
有两种不同的方法来分配标志.
标志可以是"持久"的,这意味着该标志将可用于分配给它的命令以及该命令下的每个命令.对于全局标志,在根上指定一个标志作为持久标志.
也可以在本地分配一个标志,该标志只应用于该特定命令.
默认情况下,Cobra只解析目标命令上的本地标志,而忽略父命令上的任何本地标志.通过启用Command.TraverseChildren,Cobra将在执行目标命令之前解析每个命令上的本地标志.
使用viper绑定标志
在本例中,持久标志author与viper绑定.注意:当用户未提供--author标志时,变量author将不会设置为config中的值.
更多关于 viper的文档
Flags默认是可选的,如果希望命令在未设置标志时报告错误,请根据需要进行标记:
持久性Flags
可以使用命令的Args字段指定位置参数的验证.
内置了以下验证器:
在下面的示例中,我们定义了三个命令.两个是顶级命令,一个(cmdTimes)是顶级命令之一的子命令.在这种情况下,根是不可执行的,这意味着需要一个子命令.这是通过不为"rootCmd"提供"Run"来实现的.
我们只为一个命令定义了一个标志.
有关标志的更多文档,请访问
对于一个更完整的例子更大的应用程序,请检查 Hugo .
当您有子命令时,Cobra会自动将help命令添加到应用程序中.当用户运行"应用程序帮助"时,将调用此函数.此外,help还支持所有其他命令作为输入.例如,您有一个名为"create"的命令,没有任何附加配置;调用"app help create"时,Cobra将起作用.每个命令都会自动添加"-help"标志.
以下输出由Cobra自动生成.除了命令和标志定义之外,不需要任何东西.
帮助就像其他命令一样.它周围没有特殊的逻辑或行为.事实上,你可以提供你想提供的.
您可以为默认命令提供自己的帮助命令或模板,以用于以下功能:
当用户提供无效的标志或无效的命令时,Cobra通过向用户显示"用法"来响应.
你可以从上面的帮助中认识到这一点.这是因为默认帮助将用法作为其输出的一部分嵌入.
您可以提供自己的使用函数或模板供Cobra使用.与帮助一样,函数和模板也可以通过公共方法重写:
如果在root命令上设置了version字段,Cobra会添加一个顶级的'--version'标志.运行带有"-version"标志的应用程序将使用版本模板将版本打印到标准输出.可以使用cmd.SetVersionTemplate(s string)函数自定义模板.
可以在命令的主运行函数之前或之后运行函数.PersistentPreRun和PreRun函数将在运行之前执行.PersistentPostRun和PostRun将在运行后执行.如果子函数不声明自己的函数,则它们将继承Persistent*Run函数.这些函数按以下顺序运行:
输出:
当发生"未知命令"错误时,Cobra将打印自动建议.这使得Cobra在发生拼写错误时的行为类似于git命令.例如:
如果需要在命令中禁用建议或调整字符串距离,请使用:
or
您还可以使用SuggestFor属性显式设置将为其建议给定命令的名称.这允许对在字符串距离方面不接近的字符串提供建议,但在您的一组命令中是有意义的,并且对于某些您不需要别名的字符串.例子:
Cobra可以基于子命令、标志等生成文档.请在 docs generation文档 中阅读更多关于它的信息.
Cobra可以为以下shell生成shell完成文件:bash、zsh、fish、PowerShell.如果您在命令中添加更多信息,这些补全功能将非常强大和灵活.在 Shell Completions 中阅读更多关于它的信息.
主要通过以下几个过程生成:
(一)编写模板文件
(二)配置FreeMarker
(三)统一文件生成工具
(四)数据库操作
(五)封装填充数据
FreeMarker是一款模板引擎:即一种基于模板和动态数据,用于输出文本的通用工具.
FreeMarker模板使用FreeMarker Template Language(FTL)编写,它是一种简单的、专用的语言.
代码生成器的实现原理十分简单,就是根据数据库的某一个或多个业务表的结构,生成对应的Entity.java、Dao.java、Service.java、Controller.java、Mapper.xml文件
切换到新语言始终是一大步,尤其是当您的团队成员只有一个时有该语言的先前经验.现在,Stream 的主要编程语言从 Python 切换到了 Go.这篇文章将解释stream决定放弃 Python 并转向 Go 的一些原因.
看看我如何开始 Go 教程中的一小段 Go 代码.(这是一个很棒的教程,也是学习 Go 的一个很好的起点.)
如果您是 Go 新手,那么在阅读那个小代码片段时不会有太多让您感到惊讶的事情.它展示了多个赋值、数据结构、指针、格式和一个内置的 HTTP 库.当我第一次开始编程时,我一直喜欢使用 Python 更高级的功能.Python 允许您在编写代码时获得相当的创意.例如,您可以:
这些功能玩起来很有趣,但是,正如大多数程序员会同意的那样,在阅读别人的作品时,它们通常会使代码更难理解.Go 迫使你坚持基础.这使得阅读任何人的代码并立即了解发生了什么变得非常容易. 注意:当然,它实际上有多"容易"取决于您的用例.如果你想创建一个基本的 CRUD API,我仍然推荐 Django + DRF或 Rails.
Go 的并发方法很容易使用.与 Node 相比,这是一种有趣的方法,开发人员必须密切关注异步代码的处理方式.Go 中并发的另一个重要方面是竞争检测器.这样可以很容易地确定异步代码中是否存在任何竞争条件.
Go 没有像 Rails 用于 Ruby、Django 用于 Python 或 Laravel 用于 PHP 那样的单一主导框架.这是 Go 社区内激烈争论的话题,因为许多人主张你不应该一开始就使用框架.我完全同意这对于某些用例是正确的.但是,如果有人想构建一个简单的 CRUD API,他们将更容易使用 Django/DJRF、Rails Laravel 或Phoenix.对于 Stream 的用例,我们更喜欢不使用框架.然而,对于许多希望提供简单 CRUD API 的新项目来说,缺乏主导框架将是一个严重的劣势.
Go 通过简单地从函数返回错误并期望调用代码来处理错误(或将其返回到调用堆栈)来处理错误.虽然这种方法有效,但很容易失去问题的范围,以确保您可以向用户提供有意义的错误.错误包通过允许您向错误添加上下文和堆栈跟踪来解决此问题.另一个问题是很容易忘记处理错误.像 errcheck 和 megacheck 这样的静态分析工具可以方便地避免犯这些错误.虽然这些变通办法效果很好,但感觉不太对劲.您希望该语言支持正确的错误处理.
Go 的包管理绝不是完美的.默认情况下,它无法指定特定版本的依赖项,也无法创建可重现的构建.Python、Node 和 Ruby 都有更好的包管理系统.但是,使用正确的工具,Go 的包管理工作得很好.您可以使用Dep来管理您的依赖项,以允许指定和固定版本.除此之外,我们还贡献了一个名为的开源工具VirtualGo,它可以更轻松地处理用 Go 编写的多个项目.
我们进行的一个有趣的实验是在 Python 中使用我们的排名提要功能并在 Go 中重写它.看看这个排名方法的例子:
Python 和 Go 代码都需要执行以下操作来支持这种排名方法:
与 Python 相比,我们系统的其他一些组件在 Go 中构建所需的时间要多得多.作为一个总体趋势,我们看到 开发 Go 代码需要更多的努力.但是,我们花更少的时间 优化 代码以提高性能.
我们评估的另一种语言是Elixir..Elixir 建立在 Erlang 虚拟机之上.这是一种迷人的语言,我们之所以考虑它,是因为我们的一名团队成员在 Erlang 方面拥有丰富的经验.对于我们的用例,我们注意到 Go 的原始性能要好得多.Go 和 Elixir 都可以很好地服务数千个并发请求.但是,如果您查看单个请求的性能,Go 对于我们的用例来说要快得多.我们选择 Go 而不是 Elixir 的另一个原因是生态系统.对于我们需要的组件,Go 有更成熟的库,而在许多情况下,Elixir 库还没有准备好用于生产环境.培训/寻找开发人员使用 Elixir 也更加困难.这些原因使天平向 Go 倾斜.Elixir 的 Phoenix 框架看起来很棒,绝对值得一看.
go语言抓包工具的网站:
用于将 sql 语句转换为 golang 的 struct. 使用 ddl 语句即可.
例如对于创建表的语句: show create table xxx. 将输出的语句,直接粘贴进去就行.
用于将编码后的 toml 文本转换问 golang 的 struct.
用来将 curl 命令转化为具体的 golang 代码.
用于将 json 文本转换为 struct.
GO语言简介:
Go(又称?Golang)是?Google?的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言.
Go 语言语法与?C?相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style?并发计算.
当前有两个Go编译器分支,分别为官方编译器gc和gccgo.官方编译器在初期使用C写成,后用Go重写从而实现自举.Gccgo是一个使用标准GCC作为后端的Go编译器.
官方编译器支持跨平台编译(但不支持CGO),允许将源代码编译为可在目标系统、架构上执行的二进制文件.
Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成为现实.Go 团队实施了一个看起来比较稳定的设计草案,并且正以源到源翻译器原型的形式获得关注.本文讲述的是泛型的最新设计,以及如何自己尝试泛型.
例子
FIFO Stack
假设你要创建一个先进先出堆栈.没有泛型,你可能会这样实现:
type?Stack?[]interface{}func?(s?Stack)?Peek()?interface{}?{
return?s[len(s)-1]
}
func?(s?*Stack)?Pop()?{
*s?=?(*s)[:
len(*s)-1]
func?(s?*Stack)?Push(value?interface{})?{
*s?=?
append(*s,?value)
但是,这里存在一个问题:每当你 Peek 项时,都必须使用类型断言将其从 interface{} 转换为你需要的类型.如果你的堆栈是 *MyObject 的堆栈,则意味着很多 s.Peek().(*MyObject)这样的代码.这不仅让人眼花缭乱,而且还可能引发错误.比如忘记 * 怎么办?或者如果您输入错误的类型怎么办?s.Push(MyObject{})+ 可以顺利编译,而且你可能不会发现到自己的错误,直到它影响到你的整个服务为止.
通常,使用 interface{} 是相对危险的.使用更多受限制的类型总是更安全,因为可以在编译时而不是运行时发现问题.
泛型通过允许类型具有类型参数来解决此问题:
type?Stack(type?T)?[]Tfunc?(s?Stack(T))?Peek()?T?{
func?(s?*Stack(T))?Pop()?{
func?(s?*Stack(T))?Push(value?T)?{
这会向 Stack 添加一个类型参数,从而完全不需要 interface{}.现在,当你使用 Peek() 时,返回的值已经是原始类型,并且没有机会返回错误的值类型.这种方式更安全,更容易使用.(译注:就是看起来更丑陋,^-^)
此外,泛型代码通常更易于编译器优化,从而获得更好的性能(以二进制大小为代价).如果我们对上面的非泛型代码和泛型代码进行基准测试,我们可以看到区别:
type?MyObject?struct?{
X?
int
var?sink?MyObjectfunc?BenchmarkGo1(b?*testing.B)?{
for?i?:=?0;?i?b.N;?i++?{
var?s?Stack
s.Push(MyObject{})
s.Pop()
sink?=?s.Peek().(MyObject)
var?s?Stack(MyObject)
sink?=?s.Peek()
结果:
在这种情况下,我们分配更少的内存,同时泛型的速度是非泛型的两倍.
合约(Contracts)
上面的堆栈示例适用于任何类型.但是,在许多情况下,你需要编写仅适用于具有某些特征的类型的代码.例如,你可能希望堆栈要求类型实现 String() 函数
以上就是土嘎嘎小编为大家整理的go语言模板gif相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!