构建命令行应用程序并处理系统配置。
full lessons here👇:
https://programmerscareer.com/zh-cn/golang-basic-skill/
由AI生成,可能有错误,仅供参考
1.1 Command Line Applications
命令行应用程序或 CLI 应用程序允许我们与我们的程序交互在文本界面中。这可以非常有用,用于创建脚本、自动化、服务器应用程序或当您 SSH 到服务器时。
在 Go 中,您可以编写强大且高效的 CLI 应用程序,并且 Go 提供了多个库使其变得更容易。对于我们的示例,我们将主要使用“os”和“bufio” 库。
“os” 包提供了与操作系统交互的函数和类型,以便在平台独立的情况下进行交互。”bufio” 库用于缓冲 I/O 操作,可以帮助提高 I/O 操作的效率。
以下是一个简单的 CLI 应用程序示例:
1 | package main |
在这个脚本中,我们创建了一个新的读取器,包围标准输入(os.Stdin),提示用户输入姓名,直到遇到换行符,然后将欢迎信息打印到控制台。
1.2 Handling Command Line Arguments
命令行参数可以为用户提供灵活的方式来交互您的程序。它们可能指定输入、配置或其他运行时选项,以便您的程序可以使用。
在 Go 中,这些命令行参数通过 os.Args
变量可用,该变量是一个字符串切片。请注意,os.Args[0]
是程序名称本身。
以下是一个简单的示例,它将打印所有参数:
1 | package main |
您可以使用以下方式运行它:
1 | go run main.go firstArg secondArg |
这将打印:
1 | Arg 0: /tmp/go-build123456789/command-line-arguments/_obj/exe/main |
从这里,我们可以使用参数来控制我们的应用程序。
1.3 Reading from and Writing to the Console
命令行参数虽然很有用,但有时我们需要更多交互式用户输入。这就是从标准输入读取时非常有用的情况。
我们已经在第一个主题中见过这个示例,其中我们从用户读取了一行输入。让我们探索一下,并开始介绍写入控制台的方式。
以下是一个示例脚本:
1 | package main |
这个脚本首先从用户读取了一行输入,提供了一个提示用户输入姓名的机会。然后,它确认姓名,然后提示用户输入年龄,并从控制台读取整数值。最后,它使用读取的值来显示年龄到用户。
您的任务是回顾这个脚本、运行它、玩转它,并想象其他方式可以从控制台读取或写入。
1.4 环境变量
环境变量是一种配置程序行为的优秀方式,根据它所运行的环境。它们可以存储值,如数据库连接、API密钥或任何其他您想在编译后的程序外部配置的值。
在 Go 中,可以使用 os 包轻松地读取和写入环境变量。请查看这个简单示例:
1 | package main |
在上面的示例中,我们使用 os.Setenv
创建一个名为 NAME
的新环境变量。然后,使用 os.Getenv
检索该值并将其打印出来。
请注意,使用 os.Setenv
设置的环境变量仅在当前进程中可用(即您的程序)。一旦进程停止,该变量将不再存在。
这些变量特别有助于配置根据应用程序运行环境变化的值,如本地、 staging 或生产环境。
1.5 创建配置文件
应用程序的配置是调整应用程序行为的关键步骤。它帮助我们在不更改代码的情况下调整应用程序的行为。配置可以通过多种方式注入,但在本课程中,我们将创建 .env
和 .yaml
配置文件,这些文件在许多应用程序中广泛使用。
让我们从 .env
文件开始。
Dotenv 文件
在 Go 中,常用的包用于读取 .env
文件是 godotenv。创建一个 .env
文件,并将以下内容添加到其中:
1 | GREETING=Hello from an env file |
然后,创建一个 Go 文件,并使用以下内容:
1 | package main |
在上面的脚本中,我们使用 godotenv.Load()
函数加载环境文件,然后使用 os.Getenv("GREETING")
检索该值并将其打印出来。运行 Go 脚本,并观察输出结果。
YAML 文件
YAML(YAML Ain’t Markup Language)是一种人类可读的数据序列化语言,通常用于配置文件。Go 有多个包用于解析 YAML,我们将使用最常用的包——go-yaml
。
首先,让我们创建一个 config.yaml
文件:
1 | settings: |
现在,我们将尝试从该文件中读取配置。在您的 Go 脚本中,使用以下代码:
1 | package main |
在上面的脚本中,我们首先定义 YAML 文件的结构。conf
类型说我们的根对象有一个 Settings
对象,settings
类型说 Settings
对象包含一个 Greeting
字符串。我们使用 ioutil.ReadFile
加载文件,然后使用 yaml.Unmarshal
解析该文件,并简单地打印出欢迎信息。
YAML 文件允许您创建更加复杂的结构,这可能对更大规模的应用程序非常有用。
希望这个练习能够帮助您更好地理解在 Go 中工作配置文件。记住,您主要使用这些文件来配置应用程序行为,而不是更改代码本身。
Topic 1.6: Viper 配置
Go 的标准库和许多外部包提供了管理环境变量和配置文件的工具,但是处理复杂配置的过程可能会很困难。
Viper 是一个功能强大的库,可以帮助我们处理以下内容:
- JSON、TOML、YAML、HCL 和 Java 属性配置文件
- 实时监控和重新读取配置文件
- 从环境变量中读取
- 从远程配置系统(etcd 或 Consul)中读取,并监控变化
- 设置默认值
- 创建别名
让我们初始化一个 Viper 对象,并将其设置为从环境变量中读取:
1 | package main |
正如你所看到的,Viper 允许我们使用 Go 的内置 os 包来处理环境变量,但是更加简洁和不易出错。
现在,让我们假设我们有一个名为 config.yaml
的配置文件:
1 | Port: 8080 |
我们可以使用以下方式访问这些配置设置:
1 | viper.SetConfigName("config") |
在上面的示例中,我们使用 viper.GetString
和 viper.GetInt
来获取我们的配置值。Viper 自动为我们提供正确的类型。
请尝试使用 Viper,并等待你准备好,我们可以继续构建一个完整的应用程序,该应用程序将使用到目前为止所学到的概念。
Topic 1.7: 完整应用程序 — CLI 应用程序
在本节中,我们将创建一个基于 Viper 的 CLI 应用程序,用于处理标志、环境变量和 YAML 配置文件。
我们的应用程序将是一个基本的 HTTP 服务器。让我们开始编写代码!
首先,让我们定义我们的配置:
1 | type Configuration struct { |
为了从文件或环境变量中获取配置,我们将创建一个 LoadConfiguration
函数:
1 | func LoadConfiguration(configPaths []string) (Configuration, error) { |
在这个函数中,我们将配置加载到 conf
变量中,然后返回该变量。
现在,让我们使用 LoadConfiguration 函数来启动我们的 HTTP 服务器:
1 | func main() { |
在这个示例中,我们使用 LoadConfiguration 函数来加载配置,然后启动我们的 HTTP 服务器。
请注意,需要将 "myapp"
替换为你的应用程序名称,并将实际值替换为配置路径。
Topic 1.8: Review and Practice
我们已经在这门课程中走过了很长的一段路程。让我们回顾一下你所学到的关键点:
- Go 中的命令行应用程序:你已经理解了如何使用 Go 构建 CLI 应用程序,利用标准的“os”和“bufio”库。
- 处理命令行参数:你已经学习了如何使用 os 包管理命令行参数,以及了解标志、参数和选项。
- 控制台 I/O 操作:你已经掌握了使用 “os” 和 “bufio” 包从控制台读取和写入数据。
- 环境变量:我们讨论了如何使用 os 包读取和设置环境变量,并解释了这些环境变量的重要性。
- 创建配置文件:我们探索了创建
.env
和.yaml
文件来存储应用程序配置。 - 复杂配置使用 Viper:你学习了如何使用 Viper 包处理复杂配置。
- 完整的 CLI 应用程序:使用你所学到的知识,你构建了一款功能齐全的 CLI 应用程序,演示了标志处理和环境变量配置。
现在,让我们通过一些练习来测试你的知识:
- 对 CLI 应用程序中的标志、参数和选项进行扩展。为每个提供一个例子。
- 解释如何在 Go 中使用环境变量来构建 HTTP 服务器应用程序。你将存储什么类型的信息?
- 写一段代码,演示如何在 Go 应用程序中读取
.yaml
配置文件。 - 创建一个小型的 Go CLI 应用程序,它可以从命令行参数中获取用户名称,并向用户打招呼。
这些练习将帮助你巩固所学的概念。
Topic 1.9: Assessments
这个会话将评估你的理解和应用所学到的主题。不要担心,这些问题是为了测量你的理解,而不是要 trick 你。把它当作一个反思一切所学的机会。让我们开始:
- 命令行应用程序:解释什么是命令行界面(CLI),为什么我们选择构建 CLI 应用程序,而不是图形用户界面(GUI)。
- 处理命令行参数:编写一个 Go 程序,它可以接受命令行参数并打印它们。
- 控制台 I/O 操作:编写一个 Go 程序,它从控制台读取输入字符串,并将其打印回去。
- 环境变量:编写一个 Go 程序,它可以读取环境变量并打印其值。
- 配置文件:解释使用
.env
或.yaml
文件来存储配置的用途。 - Viper 配置:编写一个 Go 程序,它从
.yaml
文件中读取 config 值,使用 viper 库。 - 完整应用程序:考虑需要多个配置(如 API 密钥或 URL)的应用程序。如何使用你所学到的知识来管理这个?
请慢慢思考,回答问题时不要匆忙。记住,这是一个反思你所学的机会。
English post: https://programmerscareer.com/go-basic-14/
作者:Wesley Wei – Twitter Wesley Wei – Medium
注意:本文为作者原创,转载请注明出处。
评论