type
status
date
category
tags
slug
summary
password
AI summary
icon
在学习 Golang 时,我发现它在语法上既有类似 C++ 和 Python 的地方,也有独特之处。与 C++ 一样,Golang 是强类型的、编译型语言,强调性能和效率,但它去除了头文件和类等复杂结构,更简洁高效。而与 Python 相似,Golang 提供了自动垃圾回收、内置的并发支持以及简洁的代码风格,减少了编码的繁琐。Golang 没有 Python 的动态类型,变量声明严格要求类型,但比 C++ 更灵活,支持类型推断。整体上,Golang 更注重简洁性和工程化,介于 C++ 的复杂和 Python 的灵活之间,特别适合并发编程和大规模应用开发。
此文章虽名为 Go 语言入门指南:基础语法和常用特性解析,实际上也是是我本人的学习笔记、学习记录、复习资料。
0x00-hello:Go 语言入门之 Hello World
学习一个新语言编写的第一个程序一定是
Hello World
。(严肃Golang 的语法与 C++、Python 非常相似,所以语法入门很轻松(其他语言没仔细学过,不清楚是否相似
(感觉变量声明和 JS 挺像,
var
关键概念
- 包声明(Package Declaration) :
package main
表示这是一个独立可执行的程序,Go 程序的执行入口必须在main
包中。
- 导入语句(Import Statement) :
import "fmt"
导入了 Go 的标准库fmt
,用于格式化输入和输出。
- 主函数(Main Function) :
func main()
定义了程序的入口函数main
,所有可执行程序都从这里开始运行。
- 输出函数(Print Function) :
fmt.Println("hello world")
使用fmt
包中的Println
函数,在控制台输出指定的字符串并换行。
代码解析
- 程序入口:
func main()
是程序的主函数,所有代码的执行都从这里开始。
- 使用标准库:通过导入
fmt
包,可以方便地使用格式化输出功能。
- 代码风格:Go 强制使用一致的代码格式,使得代码易读易维护。(Goland 用户在保存代码的时候应该能感受到
0x01-var:Go 语言变量与常量
接下来我们学习 Go 语言变量与常量的声明与类型转换
关键概念
- 变量声明:使用
var
关键字可以声明变量,支持类型推断和多变量同时声明。(感觉和 JS 类似
- 短变量声明:使用
:=
可以进行简洁的变量声明和赋值操作。
- 常量定义:使用
const
关键字定义常量,常量的值在编译时确定,不能被修改。
- 类型转换:需要显式地进行类型转换,特别是在涉及不同精度的浮点数时。
- 数学运算:通过标准库
math
可以进行数学计算,例如正弦函数math.Sin
。
代码解析
- 变量的多种声明方式:可以使用
var
关键字显式声明变量,也可以使用:=
进行隐式声明并初始化。
- 类型推断:当声明变量时,如果未指定类型,Go 会根据初始化值自动推断类型。
- 默认零值:未初始化的变量会有一个默认的零值,例如数值类型为
0
,布尔类型为false
,字符串为""
。
- 类型转换的重要性:在需要将一种类型转换为另一种类型时,必须显式地进行转换,例如将
float64
转换为float32
。
- 常量的特点:常量在程序运行期间不可改变,且可以参与编译期计算。
- 使用标准库进行数学计算:通过
math
包,可以调用数学函数,如math.Sin
计算正弦值。
0x02-for:Go 语言中的 for 循环
接下来,我们学习 Golang 的循环结构。与 C++ 相同,它可以使用
break
和 continue
来控制循环流程。关键概念
- 无限循环:使用
for {}
创建一个没有条件的循环,需要配合break
语句来终止。
- 条件循环:
for
后跟一个条件表达式,循环会在条件为true
时继续。
- 计数循环:
for
循环包含初始化语句、条件表达式和后置语句,类似于其他语言中的for
循环。
- 控制语句:
break
:立即终止循环的执行。continue
:跳过本次循环的剩余代码,直接进入下一次迭代。
代码解析
- 无限循环与
break
: for { ... }
创建了一个无限循环,但在循环体内使用了break
,所以只会执行一次,输出"loop"
。
- 计数循环:
for j := 7; j < 9; j++ { ... }
初始化了j = 7
,当j < 9
时循环,j
每次递增 1。循环体内输出7
和8
。
- 使用
continue
跳过迭代: for n := 0; n < 5; n++ { ... }
,在循环体内使用if n%2 == 0 { continue }
,当n
为偶数时跳过,输出奇数1
和3
。
- 条件循环:
for i <= 3 { ... }
,当i
小于等于3
时循环,手动增加i
的值,输出1
,2
,3
。
0x03-if:Go 语言中的 if 语句
在这章,我们主要学习 Golang 的 选择结构。
关键概念
- 条件判断:使用
if
、else if
、else
来控制程序的执行流程。
- 模运算符
%
:用于计算两个整数相除的余数,常用于判断奇偶性或可整除性。
- 短变量声明:在
if
语句中使用:=
进行变量的声明,使变量的作用域限定在条件语句内部。
代码解析
- 判断奇偶性:使用
7%2
来获取 7 除以 2 的余数,如果余数为 0,则说明是偶数,否则是奇数。(不知道是否可以像 C++ 里一样使用异或操作来判断?实测可以,但是判断条件不会隐式转换为bool 类型,Golang 中有 bool 类型吗?所以需要写等式:7&1 == 0
(有点怀念 C++ 的隐式转换了
- 判断可整除性:通过
8%4 == 0
来检查 8 是否能被 4 整除。
- 条件语句中的变量声明:在
if
语句中使用num := 9
,这样num
的作用域仅限于当前的if-else
块,提高了变量管理的局部性。
- 多重条件判断:使用
else if
来增加额外的条件判断,例如判断一个数是负数、只有一位数还是多位数。
0x04-switch:Go 语言中的 switch 语句
是那个 Switch 吗?
感觉比 C++ 的 switch-case 更好用了
关键概念
- switch 语句:用于执行多分支选择,比起多个
if-else
结构,switch
语句使代码更加清晰和简洁。
- 多条件匹配:在
case
语句中,可以使用逗号分隔多个匹配条件,实现对多个值的统一处理。
- 无条件 switch:
switch
后不跟表达式,直接在case
中编写条件判断,类似于多个if-else
结构,但更加紧凑。
- time 包:Go 的标准库,提供了时间的获取和格式化功能,例如
time.Now()
获取当前时间。
代码解析
在这段代码中,有两个主要部分:
- 基本的 switch 用法:
- 定义了变量
a := 2
。 - 使用
switch a
对变量a
的值进行匹配。 case
语句分别匹配1
,2
,3
,以及4, 5
(多个值匹配同一代码块)。- 当
a
等于2
时,匹配到case 2
,输出"two"
。 default
语句用于在没有匹配到任何case
时执行相应的代码。
- 无条件的 switch 用法:
- 使用
t := time.Now()
获取当前时间。 switch
后没有指定变量或表达式,直接在case
中编写条件。case t.Hour() < 12
判断当前时间是否在中午之前。- 根据条件,输出
"It's before noon"
或"It's after noon"
。
0x05-array:Go语言中的数组
学了循环结构,当然要学习数组啦!!
关键概念
- 数组的声明和初始化:如何声明固定长度的数组,以及给数组赋值。
- 数组的长度:使用内置函数
len()
获取数组的长度。
- 多维数组:理解如何声明和操作多维数组。
- 数组的遍历:使用循环对数组进行遍历和赋值。
代码解析
- 数组的声明:使用
var a [5]int
可以声明一个长度为5的整数数组a
,默认情况下,数组中的元素都会被初始化为零值。
- 数组元素的赋值和访问:可以通过索引来赋值或访问数组的元素。例如,
a[4] = 100
将第5个元素设置为100;a[2]
可以访问第3个元素。
- 获取数组长度:使用
len(a)
函数可以获取数组a
的长度,这对于遍历数组非常有用。
- 数组的初始化:可以在声明时直接初始化数组,例如
b := [5]int{1, 2, 3, 4, 5}
,这样b
数组就包含了指定的值。
- 打印数组:使用
fmt.Println()
可以直接打印整个数组的内容,例如fmt.Println(b)
会输出数组b
的所有元素。
- 多维数组的声明和操作:
var twoD [2][3]int
声明了一个二维数组,其大小为2x3。通过嵌套的for
循环,可以对多维数组进行遍历和赋值。twoD[i][j] = i + j
将计算结果赋值给二维数组中的每个元素。
- 遍历多维数组并赋值:使用嵌套循环,可以高效地遍历多维数组的每一个元素,这对于处理矩阵或表格数据非常有用。
注: 第一次看见 fmt.Println("2d: ", twoD) 真的很吃惊,居然能直接输出二维数组
0x06-Slice:Go 语言中的切片(Slice)应用
切片(Slice)在 Python 中可是很常用哦~
这里的语法和 Python 的很像
关键概念
- 切片(Slice) : 切片是 Go 语言中对数组的一个轻量级封装,提供了更灵活和强大的操作方式。与数组不同,切片的长度可以动态变化。
make
函数: 用于创建切片、映射和通道。make([]string, 3)
创建了一个长度为3的字符串切片。
append
函数: 用于向切片中追加元素。它会根据需要自动扩展切片的容量。
copy
函数: 用于复制一个切片到另一个切片。copy(c, s)
将切片s
的内容复制到切片c
中。
- 切片操作(Slicing) : 通过指定索引范围,可以从一个切片中创建一个新的切片。例如,
s[2:5]
获取索引2到4的元素。
- 切片字面量(Slice Literals) : 直接初始化切片的一种方式,如
good := []string{"g", "o", "o", "d"}
。
代码解析
- 切片的创建与初始化:通过
make
函数创建了一个长度为3的切片s
,并依次赋值。使用切片字面量直接初始化切片good
。
- 动态扩展切片:使用
append
函数向切片s
中追加元素,不仅可以一次追加一个元素,也可以一次性追加多个元素。这展示了切片在处理动态数据时的灵活性。
- 复制切片:通过
copy
函数将切片s
的内容复制到新切片c
中。
- 切片的切片操作:通过索引范围获取切片的子集,如
s[2:5]
获取第3到第5个元素,s[:5]
获取前5个元素,以及s[2:]
获取从第3个元素到最后的所有元素。
- 切片的长度与访问:通过
len(s)
获取切片的长度。
0x07-Map:Go 语言中的 Map 数据结构
map 就是哈希映射,类似 C++ STL 中的 map 。(不知道底层是否也是红黑树实现的呢
关键概念
- Map 数据结构:
map
是 Go 语言中用于存储键值对的数据结构,类似于其他语言中的字典或哈希表。
- 创建 Map:
- 使用
make
函数或字面量语法来创建map
。 - 例如,
m := make(map[string]int)
创建了一个键为字符串类型,值为整数类型的map
。
- 添加和更新元素:
- 通过
m["key"] = value
的方式添加或更新map
中的元素。
- 查询元素:
- 使用
m["key"]
可以获取对应键的值。如果键不存在,返回值类型的零值。 - 使用
r, ok := m["key"]
可以同时获取值和键是否存在的布尔值。
- 删除元素:
- 使用
delete(m, "key")
可以从map
中删除指定键的元素。
- Map 的长度:
len(m)
返回map
中键值对的数量。
代码解析
0x08:Go 语言中的 range
关键字使用
类似 C++ 中
range::sort(array)
里的意思,就是遍历数组全部关键概念
range
关键字:- 用于在循环中遍历切片、数组、映射、字符串等数据结构。
- 在遍历切片或数组时,
range
返回索引和值。 - 在遍历映射时,
range
返回键和值。
代码解析
在这段代码中:
- 遍历切片
nums
: - 使用
for i, num := range nums
循环遍历切片,每次迭代获取当前元素的索引i
和值num
。 - 累加
sum
变量以计算切片中所有元素的总和。 - 当
num
等于 2 时,打印出当前元素的索引和值。
- 输出总和:
- 循环结束后,打印出
sum
的值,结果为 9。
- 遍历映射
m
: - 使用
for k, v := range m
循环遍历映射,获取每个键k
和对应的值v
,并打印出来。 - 由于映射是无序的,输出的顺序可能不固定,例如
b B
和a A
。
- 仅遍历映射的键:
- 使用
for k := range m
循环仅获取映射中的键k
,并打印出来。
0x09-func:Go 语言函数应用
准备迎接嵌套和递归吧~
关键概念
- 函数定义(Function Definition) :
- 展示了如何定义函数,包括不同的参数声明方式。
- 参数声明优化(Optimized Parameter Declaration) :
- 使用简化的参数声明方式,如
func add2(a, b int) int
,提高代码的简洁性。
- 多返回值(Multiple Return Values) :
exists
函数返回两个值,展示了 Go 语言支持函数返回多个值的特性。
- 映射(Map)操作:
- 在
exists
函数中,演示了如何从 map 中检索值及其存在性。
- 函数调用与结果处理(Function Invocation and Result Handling) :
- 在
main
函数中,展示了如何调用自定义函数并处理返回结果。
代码解析
- 简洁写法:在这段代码中,
add
和add2
函数展示了两种不同的参数声明方式,add2
使用了参数类型的简化写法,使代码更加简洁。
- 多返回值特性:
exists
函数则展示了如何从 map 中检索一个键对应的值及其存在性,返回了两个值,这体现了 Go 语言函数的多返回值特性。
0x10-point:Go 语言函数与指针应用
形参和实参得分清楚哦!
与 C++ 的语法基本相似
关键概念
- 值传递(Pass by Value) :
- 在函数
add2
中,参数n
是通过值传递的。这意味着函数内部对n
的修改不会影响到函数外部的变量。
- 指针传递(Pass by Pointer) :
- 函数
add2ptr
接受一个整数指针int
作为参数。通过指针,可以直接修改原变量的值。
- 指针操作(Pointer Operations) :
- 使用
&n
获取变量n
的内存地址,并将其传递给add2ptr
。 - 在
add2ptr
函数内部,使用n
解引用指针,从而修改n
所指向的实际值。
- 变量声明与初始化:
- 使用简短声明
n := 5
初始化变量n
为5。
代码解析
在这段代码中,
add2
函数通过值传递接收参数 n
,在函数内部对 n
进行加2操作,但这种修改仅限于函数内部,不会影响到 main
函数中的变量 n
,因此第一次输出仍为5。而 add2ptr
函数通过指针传递接收参数 n
,使用解引用操作 *n
直接修改了 main
函数中变量 n
的值,使其增加到7。0x11-struct:Go 语言结构体与方法使用
通过创建不同的结构体实例来使用结构体字段。同时,程序展示了两种检查用户密码的方法:一种通过值传递,另一种通过指针传递。
关键概念
- 结构体(Struct) :
type user struct
定义了一个user
结构体,包含两个字段:name
和password
。结构体是 Go 中一种自定义的数据类型,适用于描述具有多个字段的对象,比如用户信息。
- 结构体实例化:
- 通过
user{...}
语法可以创建结构体实例,支持多种初始化方式:完整字段赋值、部分字段赋值,甚至初始化后单独赋值。
- 值传递与指针传递:
- 函数
checkPassword
使用值传递,将user
结构体的副本传入函数。 checkPassword2
使用指针传递,将user
的地址传入函数。这种方式可以避免在调用时复制整个结构体,适合较大结构体或需要在函数中修改原始数据的情况。
代码解析
- 结构体
user
定义了name
和password
两个字段。
- 主函数中,展示了四种创建和初始化结构体实例的方法:
- 使用字段名完整赋值。
- 省略字段名(按顺序赋值)。
- 部分字段赋值后,再单独设置字段值。
- 声明结构体变量后,手动为字段赋值。
checkPassword
和checkPassword2
是用于检查密码的两个函数。第一个函数接受user
结构体的值,第二个函数接受指向user
的指针。
0x12-struct_method:Go 语言中的结构体方法
类似 类(Class)的概念~
通过定义一个
user
结构体并实现与其相关的方法,程序能够检查和重置用户密码。展示了 Go 语言面向对象编程的一部分,通过结构体和方法实现对数据的封装和操作。关键概念
- 结构体(Struct) :
type user struct
定义了一个名为user
的结构体,包含两个字段:name
和password
。结构体是 Go 语言中用于组合数据的基本类型,可以看作是自定义的数据类型。
- 方法(Method) :
- 方法是与特定类型关联的函数。在本例中,
checkPassword
和resetPassword
是两个方法,分别用于检查密码和重置密码。通过这种方式,能够在逻辑上将数据和操作封装在一起。
- 值接收者与指针接收者(Value Receiver vs. Pointer Receiver) :
checkPassword
方法使用值接收者,这意味着在调用该方法时,结构体的一个副本被传递。相对而言,resetPassword
方法使用指针接收者,因此在方法中对密码的更改会影响原始结构体。这种设计允许在方法内修改结构体字段。
代码解析
结构体
user
代表用户信息,包含用户名和密码字段。通过 checkPassword
方法,可以检查输入的密码是否与存储的密码匹配,而 resetPassword
方法则提供了更新用户密码的功能。在
main
函数中,创建了一个 user
类型的实例 a
,并初始化用户名和密码。随后,调用 resetPassword
方法将密码更新为 "2048",并使用 checkPassword
验证新的密码。最终,程序输出 true
,表明密码重置成功,且检查结果符合预期。0x13-error:Go 语言中的错误处理与查找用户示例
优雅的错误信息抛出方式~
关键概念
- 错误处理:
- Go 语言推荐使用
error
接口类型来处理错误,而不是异常机制。代码中的errors.New()
用于创建自定义错误信息,便于程序在特定条件不满足时返回错误。
- 指针与值传递:
findUser
函数返回用户的指针(user
)。通过指针传递用户数据,避免复制数据,同时节省内存,特别是当用户结构体较大时。
- 短变量声明与条件语句:
if u, err := findUser(...); err != nil { ... }
是 Go 中典型的短变量声明方式,允许在一个条件表达式内定义并检查多个返回值。这样既精简了代码,又增强了可读性。
代码解析
type user struct
:定义了一个user
结构体,包含用户名和密码字段,用于模拟用户信息。
findUser
函数:该函数遍历用户列表,匹配用户名是否存在。如果找到,则返回用户指针和nil
,否则返回nil
和错误信息not found
。
main
函数:- 通过调用
findUser
查找用户,利用if err != nil
来判断是否有错误发生。这种判断机制可以让程序根据不同情况进行不同的操作,提高了代码的鲁棒性。 - 第二次调用
findUser
使用了短变量声明和条件语句的组合形式 (if u, err := ...; err != nil { ... } else { ... }
),这样可以一次性检查和处理返回值,避免多层嵌套结构,代码更加简洁。
使用
errors.New()
创建自定义错误真的很方便!!0x14-string:Go 语言字符串操作
字符串,可以玩马拉车啦~
关键概念
- 字符串不可变性:在 Go 语言中,字符串是不可变的,即一旦创建,字符串中的字符就不能被更改。如果需要修改字符串,实际上是生成了一个新的字符串。
- UTF-8 字符串长度:
len()
函数返回的是字符串的字节长度,而不是字符数。对于包含多字节字符(如中文)的字符串,字节数和字符数是不一样的。例如,"你好"
的字节长度是 6,因为每个汉字占用 3 个字节。
strings
包的字符串操作函数:- 查找子串、计数、前后缀判断、索引等都可以通过
strings
包提供的函数实现,这些操作广泛用于字符串处理。
代码解析
- 字符串查找和判断:
strings.Contains(a, "ll")
:判断子串"ll"
是否在字符串a
中。strings.HasPrefix(a, "he")
和strings.HasSuffix(a, "llo")
:判断字符串是否有指定的前缀或后缀。strings.Index(a, "ll")
:查找子串在字符串中的索引位置,如果不存在则返回1
。
- 字符串计数与替换:
strings.Count(a, "l")
:计算子串"l"
在a
中出现的次数。strings.Replace(a, "e", "E", -1)
:将字符串中的"e"
替换为"E"
,1
表示替换所有匹配的子串。
- 字符串的分隔和连接:
strings.Join([]string{"he", "llo"}, "-")
:将字符串切片按指定分隔符连接成一个新字符串。strings.Split("a-b-c", "-")
:按分隔符"-"
将字符串分割成切片。
- 字符串大小写转换:
strings.ToLower(a)
和strings.ToUpper(a)
:将字符串全部转为小写或大写。
- 字符串重复:
strings.Repeat(a, 2)
:将字符串重复指定次数。
- 字符串长度:
len(a)
:返回字符串的字节长度。在英文字符串中等于字符数,但在多字节字符(如中文)中,这个长度代表的是字节数,因此"你好"
返回6
而不是2
。
这些是很常用的字符串处理、判断函数。
0x15-fmt:Go 语言格式化输出(fmt 包)
格式化打印输出
关键概念
- 格式化输出函数:
fmt.Println
:用于简单输出,支持多变量,自动添加空格分隔和换行。fmt.Printf
:支持格式化输出,通过指定格式化标识符控制输出内容的格式。
- 格式化标识符:
%v
:通用占位符,打印变量的值。%+v
:打印结构体时会包含字段名。%#v
:打印变量的完整语法表示,适合用于调试。%.2f
:用于格式化浮点数,指定保留小数位数。
- 结构体格式化:
- 使用
fmt.Printf
可以自定义结构体的输出格式,提供更多关于结构体字段的信息。
代码解析
在这段代码中,我学到了如何使用
fmt
包进行不同的格式化输出。- 基本输出:
fmt.Println(s, n)
简单地输出了字符串和整数值,并自动添加空格和换行符,这是打印基础信息最简单的方式。
- 结构体输出:直接使用
fmt.Println(p)
可以输出结构体的字段值;而通过fmt.Printf
使用%+v
标识符可以包含字段名,比如p={x:1 y:2}
。而%#v
则输出了结构体的完整定义信息p=main.point{x:1, y:2}
,便于调试时观察结构体类型和字段信息。
- 浮点数格式化:
fmt.Printf("%.2f\\\\n", f)
控制浮点数的输出精度,让我可以只显示两位小数。这种格式化方式在处理需要特定精度的数值输出时非常实用,例如保留两位小数的金额或百分比。
0x16-json:Go 语言 JSON 序列化与反序列化
将自定义结构体序列化为 JSON 格式的字符串,以及如何将 JSON 字符串反序列化回结构体。
快速创建结构体:curlconverter
关键概念
- 结构体定义与 JSON 标签:
- 该程序定义了一个
userInfo
结构体,其中包含Name
、Age
和Hobby
字段。在Age
字段上使用了json:"age"
标签,指定该字段在 JSON 中的键名为"age"
。(不特别指出就默认键值为结构体中变量名
- JSON 序列化(Marshaling) :
- 程序使用
json.Marshal()
将userInfo
结构体实例a
转换为 JSON 格式的字节切片。json.MarshalIndent()
提供了格式化输出,增加可读性。(json.MarshalIndent()
超级好用!
- JSON 反序列化(Unmarshaling) :
- 使用
json.Unmarshal()
可以将 JSON 字节切片转换为userInfo
结构体的实例。
代码解析
- 结构体定义:
userInfo
结构体定义了用户信息的基本字段。通过在Age
字段上加上json:"age"
标签,控制了序列化后的 JSON 键名。(避免 Go 语言结构体成员的首字母大写规则导致与 JSON 字段名称不匹配的问题。
- 序列化与格式化:
- 使用
json.Marshal(a)
可以将结构体序列化为 JSON 字节切片,然后通过string(buf)
转换为字符串输出。 json.MarshalIndent(a, "", "\\\\t")
实现了格式化输出,这在调试和阅读 JSON 数据时非常有用。
- 反序列化:通过
json.Unmarshal(buf, &b)
将 JSON 字节切片转回userInfo
结构体的实例,并使用fmt.Printf
观察结构体内容,验证反序列化是否成功。
0x17-time:Go 语言时间操作
深入理解
time
包在处理日期和时间方面的基本用法。关键概念
- 获取当前时间:
time.Now()
返回当前的时间信息,包括日期、时间、时区等。这个方法用于获取程序运行时的准确时间。
- 创建指定时间:
time.Date()
允许创建一个自定义的时间实例,可以指定年、月、日、小时、分钟、秒等参数,是构建特定时间的有效方法。
- 时间格式化与解析:
Format
和Parse
是time
包中两个关键函数,用于将时间格式化为特定字符串格式以及从特定格式的字符串解析时间。
- 计算时间差:
Sub
用于计算两个时间之间的差值。Sub
返回Duration
类型,可以进一步转换为分钟或秒等单位,适用于分析时间间隔。
- Unix 时间戳:
Unix()
方法将时间转换为 Unix 时间戳(自 1970 年 1 月 1 日以来的秒数),便于存储和比较时间。
代码解析
0x18-strconv:Go 语言 strconv 包的基本使用
Go 语言标准库中的
strconv
包,主要用于处理字符串和其他数据类型之间的转换。关键概念
- strconv 包:
strconv
是 Go 的标准库包,专门用于字符串和基本数据类型(如整数、浮点数、布尔值)之间的转换。在数据处理中,经常需要将用户输入或文件中的字符串数据解析为特定类型,strconv
提供了简便的方法。
- Parse 系列函数:
strconv.ParseFloat
:将字符串解析为浮点数,支持指定精度。strconv.ParseInt
:将字符串解析为整数,支持指定进制和位数。strconv.Atoi
:将字符串直接解析为整数,是ParseInt
的简化版本,默认使用十进制。
- 错误处理:
- Go 语言的错误处理机制很明确:多数解析函数返回解析结果和错误值。在解析失败时,程序可以通过检查错误值来处理异常数据,确保代码的健壮性。
代码解析
- ParseFloat 使用:
strconv.ParseFloat("1.234", 64)
用于将字符串 "1.234" 解析为浮点数,指定 64 表示使用 64 位精度。ParseFloat
是处理浮点数的常用方法,适合需要高精度的计算场景。
- ParseInt 支持多种进制:
strconv.ParseInt("111", 10, 64)
表示将十进制字符串 "111" 解析为 64 位整数。strconv.ParseInt("0x1000", 0, 64)
体现了自动识别进制的能力,其中0x1000
是十六进制格式。ParseInt
在第二个参数为 0 时会根据前缀自动识别进制,非常方便。
- Atoi 的快捷用法:
strconv.Atoi("123")
可以快速将字符串 "123" 解析为整数,但它默认只能处理十进制。对于简单整数解析,Atoi
提供了更简洁的写法。- 尝试将非数字字符串 "AAA" 转换为整数时,
Atoi
返回了错误信息。err
值来判断转换是否成功并存储具体问题的描述。
0x19-env:Go 语言系统交互之环境变量与命令执行
Golang 还可以直接处理环境变量、读取命令行参数,并调用系统命令。
关键概念
- 命令行参数:
- Go 使用
os.Args
获取命令行传递的参数。通过这个方式,我们可以让程序根据传入的参数执行不同操作。
- 环境变量:
- 使用
os.Getenv
可以读取当前的环境变量。环境变量用于在不同的环境中传递配置信息。 os.Setenv
可以设置新的环境变量,便于在程序运行期间临时调整环境设置。
- 执行系统命令:
- 通过
exec.Command
可以调用系统命令。在此程序中,grep
被用来查找文件中的内容。使用CombinedOutput
可以获取命令的输出和错误信息。
代码解析
- 命令行参数:通过
os.Args
获取程序运行时传递的参数,这在控制程序行为时很有用。运行go run example/20-env/main.go a b c d
时,会打印出所有参数,例如[.../main a b c d]
。
- 环境变量读取与设置:使用
os.Getenv
可以读取环境变量,比如PATH
。而os.Setenv
可以设置新的环境变量,比如设置AA=BB
,但此变量仅在当前进程有效。学习到这一点帮助理解如何在 Go 中读取和动态配置环境。
- 执行系统命令:
exec.Command("grep", "127.0.0.1", "/etc/hosts")
用于执行grep
命令,查找指定内容,并获取其输出。CombinedOutput
将输出结果存储在buf
中,若命令执行失败则err
将捕获错误。这一部分展示了如何在 Go 中调用系统命令并获取输出。
- 作者:Kechang
- 链接:https://kechang.uk/article/1334fa24-e032-80ad-8b89-e305ce45d2db
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。