Go命令源码文件

Go命令源码文件

命令源码文件的用途,怎样编写它?

命令源码文件是程序的运行入口,是每个可独立运行的程序必须拥有的。如果一个源码文件声明属于 main 包,并且包含一个无参数声明且无结果声明的 main 函数,那么它就是命令源码文件。
该定义可以被解析为以下两个条件:
属于main包:在Go语言中,main 包具有特别的含义。只有属于 main 包的源文件可以被编译成一个独立的可执行文件。main 包是应用程序的入口点。
无参数声明且无结果声明的 main 函数:这意味着 main 函数不接受任何参数,也不返回任何结果。也就是说,它的声明必须是 func main()。在 Go 中,main 函数不允许有任何输入参数或返回值。它是由 Go 运行时系统直接调用的,而不是由其他代码调用的。

命令源码文件示例:
package main
import "fmt"
func main() {fmt.Println("Hello, world!")
}

当需要模块化编程时,往往会将代码拆分到多个文件,甚至拆分到不同的代码包中。
但无论怎样,对于一个独立的程序来说,命令源码文件永远只会也只能有一个。
如果有与命令源码文件同包的源码文件,那么它们也应该声明属于main包。

命令源码文件怎样接收参数?

package main
import ("flag""fmt"
)
var name string
func init() {flag.StringVar(&name, "name", "default name", "how to use this.") // 第一个参数用于存储该命令参数值的地址// 第二个参数用来指定该命令参数的名称// 第三个参数用来指定未追加该命令参数时的默认值// 第四个参数是该命令参数的简短说明
}
func main() {flag.Parse()fmt.Printf("Hello, %s!\n", name)
}

与 flag.StringVar 函数类似的函数是 flag.String。这两个函数的区别是,后者会直接返回一个已经分配好的用于存储命令参数值的地址。

package main
import ("flag""fmt"
)
var name *string
func init() {flagStringValue := flag.String("name", "default name", "how to use this.")name = flagStringValue
}
func main() {flag.Parse()fmt.Printf("Hello, %s!\n", *name)
}
go run test.go -name="Heihei"
打印结果:
Hello, Heihei
 $ go run demo.go --help
1 Usage of /var/folders/ts/7lg_tl_x2gd_k1lm5g_48c7w0000gn/T/go-build155438482/b001/exe/test
2 -name string
3 how to use this. (default "default name")
4 exit status 2

/var/folders/ts/7lg_tl_x2gd_k1lm5g_48c7w0000gn/T/go-build155438482/b001/exe/test 是 go run 命令构建上述命令源码文件时临时生成的可执行文件的完整路径。如果我们先构建这个命令源码文件再运行生成的可执行文件,像这样:

1 $ go build test.go
2 $ ./test --help
打印结果:
1 Usage of ./test:
2 -name string
3 how to use this. (default "default name")

怎样自定义命令源码文件的参数使用说明

最简单的一种方式就是对变量 flag.Usage 重新赋值flag.Usage 的类型是 func(),即一种无参数声明且无结果声明的函数类型。flag.Usage 变量在声明时就已经被赋值了,所以我们才能够在运行命令 go run demo.go --help 时看到正确的结果。注意:对 flag.Usage 的赋值必须在调用 flag.Parse 函数之前。

 flag.Usage = func() {fmt.Fprintf(os.Stderr, "Usage of %s:\n", "question")flag.PrintDefaults()
}
$ go run demo.go --help
1 Usage of question:
2 -name string
3 how to use this. (default "default name")
4 exit status 2

在调用 flag 包中的一些函数(比如 StringVar、Parse 等等)的时候,实际上是在调用 flag.CommandLine 变量的对应方法。flag.CommandLine 相当于默认情况下的命令参数容器。所以,通过对 flag.CommandLine 重新赋值,可以更深层次地定制当前命令源码文件的参数使用说明。现在我们把 main 函数体中的那条对 flag.Usage 变量的赋值语句注销掉,修改为如下代码:

package main
import ("flag""fmt""os"
)
var name string
func init() {flag.CommandLine = flag.NewFlagSet("", flag.ExitOnError)flag.CommandLine.Usage = func() {fmt.Fprintf(os.Stderr, "Usage of %s:\n", "question")flag.PrintDefaults()}flag.StringVar(&name, "name", "default name", "how to use it.")
}
func main() {flag.Parse()fmt.Printf("Hello, %s!\n", name)
}

现在修改为如下代码:

import ("flag""fmt""os"
)
var name string
func init() {flag.CommandLine = flag.NewFlagSet("", flag.PanicOnError)flag.CommandLine.Usage = func() {fmt.Fprintf(os.Stderr, "Usage of %s:\n", "question")flag.PrintDefaults()}flag.StringVar(&name, "name", "default name", "how to use it.")
}
func main() {flag.Parse()fmt.Printf("Hello, %s!\n", name)
}
--------------------------------------------------------------------------------
PS D:\TestPro> go run test.go --help
Usage of question:-name stringhow to use it. (default "default name")
goroutine 1 [running]:
flag.(*FlagSet).Parse(0xc0000740c0, {0xc0000663d0, 0x6a5ab9, 0x60})D:/GO/src/flag/flag.go:1021 +0xe8
flag.Parse(...)D:/GO/src/flag/flag.go:1036
main.main()D:/TestPro/test.go:20 +0x5f
exit status 2

运行 go run test.go --help 命令就会产生另一种输出效果。
这是由于我们在这里传给 flag.NewFlagSet 函数的第二个参数值是 flag.PanicOnError。
flag.PanicOnError 和 flag.ExitOnError 都是预定义在 flag 包中的常量。
flag.ExitOnError 的含义是,告诉命令参数容器,当命令后跟 --help 或者参数设置的不正确的时候,在打印命令参数使用说明后以状态码 2 结束当前程序。状态码2代表用户错误地使用了命令。
flag.PanicOnError 与 flag.ExitOnError 的区别是在最后抛出"运行时恐慌( panic )"。
上述两种情况都会在调用 flag.Parse 函数时被触发。

再进一步,创建一个私有的命令参数容器。
在函数外再添加一个变量声明:var cmdLine = flag.NewFlagSet(“question”, flag.ExitOnError)
然后,把 flag.StringVar 调用替换为 cmdLine.StringVar ,再把 flag.Parse() 替换为 cmdLine.Parse(os.Args[1:])。 其中的 os.Args[1:] 指的就是给定的那些命令参数。
这样完全脱离了 flag.CommandLine。好处是更灵活地定制命令参数容器。
但更重要的是,你的定制完全不会影响到那个全局变量flag.CommandLine。

package main
import ("flag""fmt""os"
)
var name string
func init() {var cmdLine = flag.NewFlagSet("question", flag.ExitOnError)cmdLine.StringVar(&name, "name", "default", "help")cmdLine.Parse(os.Args[1:])
}
func main() {fmt.Printf("Hello, %s!\n", name)
}

默认情况下,可以让命令源码文件接受哪些类型的参数值?

有布尔类型、整数类型、浮点数类型、字符串类型,以及time.Duration类型。
● string
● int, int64
● uint, uint64
● float64
● bool

可以把自定义的数据类型作为参数值的类型吗?如果可以,怎样做?

可以定义自己的数据类型作为命令行参数值的类型。
为了实现这个功能,需要定义一个新类型,并为这个类型实现 flag.Value 接口。这个接口要求实现以下两个方法:
● String() string:返回参数的字符串表示形式。
● Set(string) error:解析并设置参数的值。

package main
import ("flag""fmt"
)
// 定义一个自定义的类型
type myCustomType struct {value string
}
// 实现 flag.Value 接口的 String 方法
func (c *myCustomType) String() string {return c.value
}
// 实现 flag.Value 接口的 Set 方法
func (c *myCustomType) Set(s string) error {// 这里可以加入对值的解析和验证逻辑c.value = sreturn nil
}
func main() {var customVal myCustomType// 使用 flag.Var 函数将自定义类型绑定到命令行参数flag.Var(&customVal, "custom", "A custom flag value")flag.Parse()fmt.Printf("Custom flag value: %s\n", customVal.String())
}
# type Value interface {
# 	String() string
# 	Set(string) error
# }
PS D:\TestPro> go run test.go -custom="test"
Custom flag value: test

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/706191.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[HackmyVM]靶场 Azer

kali:192.168.56.101 主机发现 arp-scan -l靶机:192.168.56.103 端口扫描 nmap -p- 192.168.56.103 开启了80 3000端口 看一下80端口 一直在那转,看源码也没什么有用的东西 扫一下目录 扫不到什么东西 看看另一个端口 是个登录界面 输入admin/admin测试 错误…

Kafka入门二——SpringBoot连接Kafka示例

实现 1.引入maven依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache…

2-25算法习题总结

贪心问题 P1803 凌乱的yyy / 线段覆盖 凌乱的yyy / 线段覆盖 题目背景 快 noip 了&#xff0c;yyy 很紧张&#xff01; 题目描述 现在各大 oj 上有 n n n 个比赛&#xff0c;每个比赛的开始、结束的时间点是知道的。 yyy 认为&#xff0c;参加越多的比赛&#xff0c;no…

基于springboot+vue的学科平台系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

代码随想录三刷day13

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣151. 反转字符串中的单词二、力扣55. 右旋字符串&#xff08;第八期模拟笔试&#xff09;三、力扣28. 找出字符串中第一个匹配项的下标 前言 KMP主要应…

轻量级模型,重量级性能,TinyLlama、LiteLlama小模型火起来了,针对特定领域较小的语言模型是否与较大的模型同样有效?

轻量级模型&#xff0c;重量级性能&#xff0c;TinyLlama、LiteLlama小模型火起来了&#xff0c;针对特定领域较小的语言模型是否与较大的模型同样有效? 当大家都在研究大模型&#xff08;LLM&#xff09;参数规模达到百亿甚至千亿级别的同时&#xff0c;小巧且兼具高性能的小…

Mysql8.0 字符集

在8.0版本之前&#xff0c;MySQL默认的字符集为latin1&#xff0c;而8.0版本默认的字符集为utf8mb4。 latin1是ISO-8859-1的别名&#xff0c;有些环境下写作latin-1。ISO-8859-1编码是单字节编码&#xff0c;不支持中文等多字节字符&#xff0c;但向下兼容ASCII&#xff0c;其编…

学生信息的那些操作:(3)按姓名,查个人

有一学生成绩表&#xff0c;包括学号、姓名、3门课程成绩。请实现如下查找功能&#xff1a;输入一个学生的姓名&#xff0c;输出该学生学号、姓名、3门课程成绩 输入格式: 首先输入一个整数n(1<n<100)&#xff0c;表示学生人数&#xff1b; 然后输入n行&#xff0c;每…

关于CSS 盒子模型的基础教程

什么是CSS盒子模型&#xff1f; 在学习CSS布局时&#xff0c;一个非常重要的概念就是盒子模型。CSS盒子模型描述了网页中元素的布局方式&#xff0c;每个元素都被看作一个矩形的盒子&#xff0c;这个盒子包含了内容、内边距、边框和外边距四个部分。 盒子模型的组成部分 盒子…

Linux环境基础开发工具使用篇(三) git 与 gdb

一、版本控制器-git 1.简单理解: ①git既是服务端&#xff0c;又是客户端 ②git会记录版本的变化 ③git是一个去中心化的分布式软件 git/gitee 是基于git仓库搭建的网站&#xff0c;让版本管理可视化 2.git 三板斧提交代码 查看安装的git版本 git--version 命令行提交代…

FPGA IO命名与Bank划分

文章目录 IO的命名IO物理命名IO功能命名 Bank简介FPGA器件功能命名与Bank划分查找XILINXIntelLATTICE IO的命名 IO物理命名 FPGA的IO物理命名规则&#xff0c;也就是我们做管脚约束时候的命名。芯片通常是长方体或者正方体&#xff0c;所以命名通常采用字母数字组合的方式&am…

FMM 笔记:st-matching(colab上执行)【官方案例解读】

在colab上运行&#xff0c;所以如何在colab上安装fmm&#xff0c;可见FMM 笔记&#xff1a;在colab上执行FMM-CSDN博客 st-matching见论文笔记&#xff1a;Map-Matching for low-sampling-rate GPS trajectories&#xff08;ST-matching&#xff09;-CSDN博客 0 导入库 from…

华为畅享 60X 到底值得入手吗?这4点你必须要知道

作为一款主打千元机市场的机型&#xff0c;华为畅享 60X 到底怎么样&#xff1f;是否值得入手&#xff1f; 可以负责任的说华为畅享 60X 是一款性价比超高的手机&#xff0c;凭借其出色的硬件配置和适中的价格&#xff0c;不仅拥有华为完整的鸿蒙生态&#xff0c;同时它超大屏幕…

电源轨概念讲解

目录 1、电源轨定义2、模拟运放中电源轨概念3、芯片中电源轨概念 在电子设计中&#xff0c;我们经常会听到电源轨的概念&#xff0c;下面就针对他的定义和模电中的习惯叫法做一个简单的讲解&#xff1a; 1、电源轨定义 电源轨是指电路板上传输电力的线路&#xff0c;只要是连接…

【DL】深度学习之语音识别

目录 1 核心概念 2 安装依赖库 3 实践 语音信号处理&#xff08;Speech Signal Processing&#xff09;简称语音处理。 语音识别&#xff08;ASR&#xff09;和自然语言处理&#xff08;NLP&#xff09;&#xff1a;语音识别就是将语音信号转化成文字文本&#xff0c;简单实…

go 解压和压缩包

將压缩包放在zippath"D:/xx/xx/xx"中,解压到pathto"D:/xx/xx1/xx"中 type UploaddeployLogic struct {logx.Loggerctx context.ContextsvcCtx *svc.ServiceContextr *http.Request }func NewUploaddeployLogic(r *http.Request, svcCtx *svc.Serv…

Spring-Cloud-Gateway集成Sentinel限流

1&#xff09;gateway添加sentinel相关依赖 <spring-cloud.version>2021.0.1</spring-cloud.version> <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version><dependencies><!--gateway--><dependency><gro…

Linux yum与rpm区别

yum和rpm都是Linux系统中用于安装、升级和管理软件包的工具&#xff0c;但它们有一些区别。以下是yum和rpm的主要区别&#xff1a; 1. 功能&#xff1a;rpm是一种软件包管理工具&#xff0c;用于安装、升级和卸载软件包。它可以直接操作软件包文件&#xff0c;但不提供依赖关系…

JQUERY简介与分析

在现代的前端开发中&#xff0c;jQuery无疑是一个非常重要且广泛使用的工具库。它不仅简化了JavaScript的编写&#xff0c;还提供了丰富的功能和强大的选择器&#xff0c;使开发者能够更轻松地操作DOM元素、处理事件和实现动态效果。 简单来说&#xff0c;jQuery是一个快速、简…

【主流开发语言和开发环境介绍】

主流开发语言和开发环境介绍 1. 介绍2. 开发语言3. 开发环境 1. 介绍 下面是一些广泛使用的主流开发语言及其相关的开发环境。 2. 开发语言 Python 用途&#xff1a;通用编程、科学计算、数据分析、机器学习、Web开发等。流行库&#xff1a;NumPy, Pandas, TensorFlow, PyTor…