这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
1.1什么是go语言
- 高性能,高并发
- 语法简单,学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
//简单的http服务器
package main
import "net/http"
func main() {
http.Handle("/",http.FileServer(http.Dir(".")))//把斜杠指向一个静态路由的实现
http.ListenAndServe(":8080",nil)//增加8080端口,启动服务器
}
02入门
- 安装Golang(跳过)
- 开发环境 - 配置集成开发环境(Vscode下载Go插件)
2.2基础语法 - Hello World
导入fmt包在Go语言中主要用于格式化输入输出. fmt包中提供了很多函数,如Printf、Sprintf、Fprintf等,可以用来格式化输出字符串,还有Scanf、Sscanf、Fscanf等,可以用来读取格式化的字符串
package main//main包的一部分,程序的入口包(入口文件)
import "fmt"//导入fmt包,作用:格式化输入输出
func main() {
fmt.Println("Hello World")
}
2.3基础语法 - 变量
变量声明的两种方式:
显式声明:通过关键字var来声明一个变量,格式如下:
//var variable_name variable_type var age int var name string隐式声明:通过简写的方式声明变量,省略了var关键字,格式如下:
//variable_name := value age := 18 name := "John"两种声明方式的区别:第二种方式只能在函数体内使用, 第一种可以在函数体外使用
package main
import (
"fmt"
"math"
)
func main() {
//声明方式1
var a = "initial"
var b,c int = 1,2
var d = true
var e float64
//声明方式2
f := float32(e)
g := a + "foo"
//Go中不允许变量不被使用,如果你定义了不使用会报错
fmt.Println(a,b,c,d,e,f)//initial 1 2 true 0 0
fmt.Printf(g)//initialfoo
//Go中的常量没有特定的类型,而是根据使用的上下文来自动确定类型
const s string = "2002XiaoYu"
const h = 500000000//5亿,8个0
const i = 3e20/h
fmt.Println(s,h,i,math.Sin(h),math.Sin(i))
//2002XiaoYu 500000000 6e+11 -0.28470407323754404 0.7591864109375384
2.4基础语法 - if else
不同点:
- if后面没有括号,也就是不是if(xxx)这种形式,而是if xxx这种形式。如果你加上括号,编辑器会在运行前自动去掉
- Go中的if语句具有自动类型转换特性, 也支持在条件判断语句前执行简单的语句
package main
import (
"fmt"
)
func main() {
i := 1
//for中什么都不写就是死循环
for {
fmt.Println("2002XiaoYu")
break
}
//for跟if一样,从其他语言中for(){}省略掉了()
for j := 7; j < 9; j++ {
fmt.Println(j)
}
for n := 0; n < 5; n++ {
if n%2 == 0 {
continue//继续循环,或者使用break跳出循环
}
fmt.Println(n)
}
for i <= 3 {
fmt.Println(i)
i = i + 1
}
}
//2002XiaoYu
//7
//8
//1
//3
//1
//2
//3
2.5基础语法 - switch
- switch语句中的变量可以是任何类型,可以是一个常量或者一个变量,在每个case后面可以跟多个值,用逗号隔开
- Go中的switch语句也支持在条件判断语句前执行简单的语句,这样就可以在一个switch语句中处理多个条件
package main
import (
"fmt"
"time"
)
func main() {
a := 2
switch a {
case 1:
fmt.Println("小余学习Go第一天")
case 2:
fmt.Println("小余学习Go第二天")
case 3:
fmt.Println("小余学习Go第三天")
case 4, 5:
fmt.Println("小余学习Go第四或者第五天")
default:
fmt.Println("小余学习不再前5天内了")
}
//输出:小余学习Go第二天
t := time.Now()
//优势:比多个if嵌套更加清晰易懂
switch {//在switch中不加判断条件,而是在case中去写条件分支,这样可以处理多个条件
case t.Hour() < 12:
fmt.Println("中午12点之前")
default:
fmt.Println("中午12点过后")
}
//输出:中午12点之前
}
2.6基础语法 - 数组
在开发中我们很少直接使用数组,因为数组的长度是固定的。我们更多情况下是使用切片
数组跟其他语言都差不多,不过多赘述
package main
import "fmt"
func main() {
var a [5]int
a[4] = 520
fmt.Println(a[4], len(a)) //520 5
b := [5]int{1, 2, 3, 4, 5}
fmt.Println(b) //[1 2 3 4 5]
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
fmt.Println("2d:", twoD) //2d: [[0 1 2] [1 2 3]]
}
2.7基础语法 - 切片
切片 (slice) 是一种对数组的抽象,可以让你动态地管理数组中的元素。切片是一个指向底层数组的指针,并且包含了三个属性:指针、长度和容量
切片的语法格式如下:
var slice_name []type = array_name[start_index : end_index]切片可以通过下标访问数组中的元素,并且支持切片赋值和切片比较操作。
package main import "fmt" func main() { arr := [5]int{1, 2, 3, 4, 5} slice := arr[1:4] fmt.Println(slice) // Output: [2 3 4] }切片可以通过内置函数make()来创建,格式如下:
make([]type, len, cap)它返回一个初始化之后长度为len,容量为cap的切片.
切片也可以通过内置函数append()来动态地增加元素.
package main import "fmt" func main() { slice := []int{1, 2, 3} slice = append(slice, 4, 5) fmt.Println(slice) // Output: [1 2 3 4 5] }切片是Go语言中的重要类型之一, 它可以帮助我们更方便地管理数组.
package main
import "fmt"
func main() {
//使用make创建切片
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("获取:", s[0])//获取: a
fmt.Println("长度:", len(s))//长度: 3
//切片可以使用append追加元素
s = append(s, "d")
s = append(s, "e", "f") //记得双引号不能打成单引号
fmt.Println(s)//[a b c d e f]
//使用make的时候也可以直接指定长度进行创建
c := make([]string, len(s))
copy(c, s) //使用copy拷贝数值
fmt.Println(c)//[a b c d e f]
fmt.Println(s[2:5])//[c d e] 取出第二个到第五个元素之前(不包括第五个元素,意思其实就是2<=x<5的范围)
fmt.Println(s[:5])//[a b c d e] 取出5之前的元素,0 1 2 3 4
fmt.Println(s[2:])//[c d e f] 取出第二个及以后的元素,除了下标0 1的元素不取,其他全要
good := []string{"好", "好", "学", "习"}
fmt.Println(good)//[好 好 学 习]
}
2.8基础语法 - map
Go语言中的map是一种内置数据结构,用于存储键值对。键必须是可比较的数据类型(如字符串、整数等),值可以是任何数据类型。map可用于统计字符串中单词出现次数或维护用户信息数据库等任务。可以使用
make函数创建新的map
- 在其他语言中,他可能叫做哈希或者字典
- map遍历时完全无序的,不会按照字母或者插入顺序
package main
import "fmt"
func main() {
m := make(map[string]int)//这将创建一个空map,其中键是字符串,值是整数
m["one"] = 1 //one是键,1是值
m["two"] = 2
fmt.Println(m) //map[one:1 two:2]
fmt.Println(len(m)) //2
fmt.Println(m["one"]) //1
fmt.Println(m["unknow"]) //0
r, ok := m["unknow"] //使用索引运算符检索特定键的值
fmt.Println(r, ok) //0 false
delete(m, "one") //使用delete函数从map中删除键值对
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
println(m2, m3) //0xc000143da0 0xc000143d70
}
2.9基础语法 - range
在 Go 中,
range关键字用于遍历数组、切片、字符串、map 和通道中的元素。对于数组、切片和字符串,它将返回每个元素的索引和值。对于 map,它将返回每个键和值。对于通道,它将返回每个从通道中接收到的值。在遍历数组、切片和字符串时,可以使用下面的语法:
for index, value := range array { // do something with index and value }对于 map 的遍历:
for key, value := range m { // do something with key and value }对于通道,可以在循环中使用 range 从通道中接收数据,直到该通道关闭
for value := range channel { // do something with value }在上面的例子中,我们忽略了索引或键,在遍历时如果不使用可以用 _ 来忽略这个变量
for _, value := range array { // do something with value }注意:在 map 中遍历时,顺序是不确定的。如果您需要以特定顺序遍历 map,可以先将键存储在切片中,然后使用该切片遍历键。
package main
import "fmt"
func main() {
nums := []int{2, 3, 4}
sum := 0
for i, num := range nums {
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num)//index: 0 num: 2
}
}
fmt.Println(sum)//9
m := map[string]string{"a": "A", "b": "B", "c": "C"}
for k, v := range m {//返回每个键和值
fmt.Println(k, v)//c C a A b B
}
for k := range m {
fmt.Println("key:", k)//key: b key: c key: a
}
}
2.10基础语法 - 函数
在 Go 中,函数是一组可重用的代码块,可以在程序中多次调用。函数在 Go 中是一等公民(跟JS一样),可以像其他数据类型一样赋值给变量、作为参数和返回值
定义一个函数需要使用关键字
func, 函数名称,参数和返回值。func functionName(parameterName type) returnType { // function body }Go 中也支持匿名函数和闭包,这种函数在定义时不需要函数名。
Go 中的函数还可以有可选的命名返回值参数,这样可以在函数内部直接使用这个变量并在函数结束时返回这个变量的值。这样做可以避免在函数内部声明一个局部变量并在函数结束时返回该变量的值
在 Go 中,函数也可以是一个类型。这意味着我们可以将函数作为参数传递给另一个函数,或者将函数赋值给变量。
例如,这是一个接受一个函数作为参数的函数:
func apply(fn func(int) int, x int) int { return fn(x) }这样我们可以传递一个自定义的函数来应用在特定的值上:
f := func(x int) int { return x * x } result := apply(f, 2) fmt.Println(result) // output: 4或者直接传递匿名函数:
result := apply(func(x int) int {return x*x}, 2) fmt.Println(result) // output: 4这种将函数作为参数或返回值的能力称为函数式编程。这种编程方式可以提高代码的可重用性和灵活性
package main
import "fmt"
//Go跟其他语言很不一样的地方在于他的类型是后置的,别人是int a,在Go中是a int
func add(a int,b int) int {//这是一个简单的加法函数,它接受两个整数并返回它们的和
return a+b
}
func add2(a,b int) int {
return a+b
}
//Go 中的函数可以有多个返回值(第一个值是真正的返回结果,第二个值是错误信息)。这些值可以通过在函数名称后面添加圆括号来返回
func exists(m map[string]string,k string) (v string,ok bool) {
v,ok = m[k]
return v,ok//v就是结果,ok则是错误信息,是布尔类型
}
func main() {
res := add(1,2)//调用函数使用函数名称和传递给函数的参数
fmt.Println(res)//3
v,ok := exists(map[string]string{"a":"A"},"a")
fmt.Println(v,ok)//A true
}
2.11基础语法 - 指针
在 Go 中,指针是指向一个变量的地址的变量。指针存储了变量的内存地址,因此可以通过指针来访问和更改变量的值。
创建指针需要使用
&符号,它表示取地址运算符。例如,这是一个创建指针的示例:x := 1 var p *int = &x访问指针变量所指向的值,需要使用
*符号,它表示指针间接寻址运算符。 例如,这是一个访问指针所指向的值的示例:fmt.Println(*p) // output: 1也可以使用指针来更改变量的值
*p = 2 fmt.Println(x) // output: 2Go语言中的指针不支持指针运算(如指针加法或指针减法),也不支持指针比较。
使用指针可以节省内存,因为在传递大的数组或结构体时只需要传递指针,而不是整个数组或结构体。同时,指针还可以让我们在不同函数之间共享数据,从而提高代码的可重用性。
对于指针,需要注意的是当指针指向的内存被释放时,使用这个指针就会导致运行时错误,因为该指针指向的内存已不再存在。这种错误称为野指针(dangling pointer)。
如果你使用了一个指向已经释放的内存的指针,可能导致程序崩溃,或者读取或写入非法内存。这可能导致数据不一致和难以调试的问题。
此外,在 Go 中,如果一个指针指向了一个未初始化的变量,它也可能导致运行时错误。因此,在使用指针时需要特别小心,确保指针指向的内存是有效的。
package main
import "fmt"
func add2(n int) {//函数中的参数默认是传值调用,也就是说,函数会接收一个变量的副本,而不是变量本身
n += 2//这是无效的
}
func add2ptr(n *int) {//而 add2ptr 函数中的参数是一个指针,它指向的是 main 函数中的 n 变量
*n += 2
}
func main() {
n := 5
add2(n)//在 add2 函数中,对 n 变量的更改不会影响 main 函数中的 n 变量。
fmt.Println(n)//5
add2ptr(&n)//因此,在 add2ptr 函数中对 *n 的更改会影响到 main 函数中的 n 变量。需要加上取地址符&来获取变量的内存地址
fmt.Println(n)//7
}
//如果你希望在函数中更改变量的值,需要使用指针
2.12基础语法 - 结构体
在 Go 中,结构体是一种用户定义的数据类型,它可以用来组合不同类型的数据。结构体是一组字段(类似于其他语言中的成员变量或属性)。
定义结构体需要使用关键字
type和struct。每个字段都有一个名称和类型。
package main
import "fmt"
//这是一个简单的结构体定义。表示一个用户的账号跟密码
type user struct {
name string
password string
}
func main() {
//方式1:创建一个结构体变量需要使用结构体类型名称和对应的值
a := user{name: "小余", password: "2002"}
//也可以通过结构体字段的顺序来创建,我讲用户的name跟password省略掉了
b := user{"大余", "1997"}
//方式2:可以不全部赋值完,后面再通过点号(.)来访问进行赋值
c := user{name: "小满"}
c.password = "520520"
//方式3:声明一个结构体变量而不赋值,后面再进行赋值操作。
var d user
d.name = "2002XiaoYu"
d.password = "666"
fmt.Println(a, b, c, d)//{小余 2002} {大余 1997} {小满 520520} {2002XiaoYu 666}
fmt.Println(checkPassword(a, "haha"))//false
fmt.Println(checkPassword2(&a, "haha"))//false
//访问结构体字段使用点号(.)
fmt.Println(a.name)//小余
}
//进行比较密码
func checkPassword(u user, password string) bool {
return u.password == password
}
func checkPassword2(u *user, password string) bool {
return u.password == password
}
2.13基础语法 - 结构体方法
结构体可以定义方法,这些方法可以通过结构体实例调用。结构体方法的定义格式如下:
func (receiverType receiverName) methodName(args) returnType { // method body }其中:
- receiverType 是接收器的类型,通常是结构体类型
- receiverName 是接收器的名称,在方法中可以通过这个名称访问结构体的字段
- methodName 是方法名
- args 是方法的参数
- returnType 是方法的返回类型
package main
import "fmt"
type user struct {
name string
password string
}
// 比较密码 从普通函数变成类成员函数
func (u user) checkPassword(password string) bool {
return u.password == password
}
// 修改密码 指针接收器,即通过结构体指针来调用方法 这样就可以通过结构体指针改变结构体内部的值了
func (u *user) resetPassword(password string) {
u.password = password
}
func main() {
a := user{name: "小余", password: "2002"}
fmt.Println(a)//修改前:{小余 2002}
a.resetPassword("6666")
fmt.Println(a)//修改后:{小余 6666}
fmt.Println(a.checkPassword("6666")) //比较密码,或者说是确认密码是否为6666,结果返回布尔值true
}
2.14基础语法 - 错误处理
在 Go 语言中,错误处理是一个重要的部分。Go 提供了一种简单的方法来处理错误,即将错误作为函数的返回值。
在 Go 中,错误是一个内置的 error 类型,该类型实现了 error 接口。在错误发生时,函数可以返回一个 error 值
func divide(a, b int) (int, error) { if b == 0 { return 0, fmt.Errorf("division by zero") } return a / b, nil }在这个例子中,divide 函数接受两个 int 参数,并返回一个 int 和一个 error。如果 b 等于 0,那么 divide 函数会返回一个 error,表示除数为 0。如果 b 不等于 0,那么 divide 函数会返回 a / b 和 nil。
在调用 divide 函数时,可以使用 if 语句来检查 error 是否为 nil,如下所示:
result, err := divide(10, 2) if err != nil { fmt.Println("Error:", err) return } fmt.Println("Result:", result)在Go语言中,
nil是一个特殊的值,可以赋值给任何有引用类型的变量或数据结构(如指针、切片、映射或通道)。它表示缺少值,等价于其他编程语言中的null。当一个变量或数据结构设置为nil时,表示它不指向任何有效的内存位置。尝试访问或使用值为nil的变量或数据结构可能会导致运行时错误。
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
//写上(v *user, err error),证明我们需要返回两个值,其中一个是错误信息
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil//没有错误则返回原本的结果和一个nil
}
}
return nil, errors.New("not found")//如果要return,必须同时返回两个值
}
func main() {
u, err := findUser([]user{{"小余", "6666"}}, "小余")//接收的时候也需要写两个变量
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name) //小余,只有没有nil的时候才能取值,不然会发生错误
if u, err := findUser([]user{{"小余", "6666"}}, "li"); err != nil {
fmt.Println(err) //not found
return
} else {
fmt.Println(u.name)
}
}
2.15基础语法 - 字符串操作
package main
import (
"fmt"
"strings"
)
func main() {
a := "hello"
//判断该字符串中是否包含另一个字符串
fmt.Println(strings.Contains(a, "ll")) //true
//字符串计数
fmt.Println(strings.Count(a, "l")) //2
//接受一个字符串和一个前缀作为参数,并判断该字符串是否以该前缀开头。如果是,函数返回 true,否则返回 false
fmt.Println(strings.HasPrefix(a, "he")) //true
//接受一个字符串和一个后缀作为参数,并判断该字符串是否以该后缀结尾。如果是,函数返回 true,否则返回 false
fmt.Println(strings.HasSuffix(a, "llo")) //true
//查找字符串的位置
fmt.Println(strings.Index(a, "ll")) //2
//连接多个字符串
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) //he-llo
//重复多个字符串
fmt.Println(strings.Repeat(a, 2)) //hellohello
//替换字符串的某一部分
fmt.Println(strings.Replace(a, "e", "E", -1)) //hEllo
//去掉字符串的某一部分
fmt.Println(strings.Split("a-b-c", "-")) //[a b c]
//字符串转换小写
fmt.Println(strings.ToLower(a)) //hello
//字符串转换大写
fmt.Println(strings.ToUpper(a)) //HELLO
b := "你好"
//获取字符串的长度,一个中文会对应多个字符
fmt.Println(len(b)) //6
}
2.16基础语法 - 字符串格式化
在Go语言中,有几种方法格式化字符串。最常用的方法是使用
fmt包格式化字符串中的占位符可以是 %d, %s, %f, %v 等等
在Go语言中,
%+v和%#v是fmt包中使用的两个格式化动词。
%+v会输出详细的值信息,包括结构体字段名称和值。%#v会输出详细的值信息,包括类型和值, 这个值得输出格式是一个可以直接复制粘贴到程序中使用的 Go 代码。两个动词都能输出变量的值,但是 %+v 输出更多的信息,而%#v输出的是能直接用于程序中的代码,如果你想看结构体的详细信息,%+v更加友好。
package main
import "fmt"
type point struct {
x, y int
}
func main() {
s := "hello"
n := 123
p := point{1, 2}
fmt.Println(s, n) //hello 123
fmt.Println(p) //{1 2}
//%v可以打印任何变量,数字用:%d,字符串用:%s,获取更加详细的结果:%+v,在详细上进一步详细:%#v
fmt.Printf("s=%v\n", s) //s=hello
fmt.Printf("s=%v\n", n) //s=123
fmt.Printf("s=%v\n", p) //s={1 2}
fmt.Printf("s=%+v\n", p) //s={x:1 y:2}
fmt.Printf("s=%#v\n", p) //s=main.point{x:1, y:2}
f := 3.141592653
fmt.Println(f) //3.141592653
fmt.Printf("%.2f\n", f) //3.14
}
2-17基础语法 - JSON处理
Go语言中可以使用标准库中的
encoding/json包来进行JSON处理。这个包提供了编码和解码JSON数据的函数和类型。可以使用json.Marshal函数将 Go 值编码为 JSON 数据,使用json.Unmarshal函数将 JSON 数据解码为 Go 值。
package main
import (
"encoding/json"
"fmt"
)
//只要保证结构体每个字段的第一个字母是大写即可
type userInfo struct {
Name string
Age int `json:"age"`//结构体字段需要添加json标签来指定对应json中的key值。,将Age输出首字母改成小写的age
Hobby []string
}
func main() {
a := userInfo{Name: "小余", Age: 20, Hobby: []string{"Golang", "TypeScript"}}
//通过json.Marshal序列化
buf, err := json.Marshal(a)
if err != nil {
panic(err)
}
//序列化后变成but数组,需要转换成字符串,不然会打印出16进制的编码
fmt.Println(buf)
//[123 34 78 97 109 101 34 58 34 229 176 143 228 189 153 34 44 34 97 103 101 34 58 50 48 44 34 72 111 98 98 121 34 58 91 34 71 111 108 97 110 103 34 44 34 84 121 112 101 83 99 114 105 112 116 34 93 125]
//通过转换成字符串即可输出我们的内容
fmt.Println(string(buf))//{"Name":"小余","age":20,"Hobby":["Golang","TypeScript"]}
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
//反序列化到空变量b中
err = json.Unmarshal(buf, &b)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b)//main.userInfo{Name:"小余", Age:20, Hobby:[]string{"Golang","TypeScript"}}
}
2-18基础语法 - 时间处理
Go语言中使用
time包来处理时间。time.Time是 Go 中处理时间的核心类型,它表示一个确切的时刻,并提供了很多方法来操作和格式化时间还有就是Go语言中的时间是以纳秒为单位存储的,所以你从年开始往后写,要写7位数
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
//快速获取当前时间
fmt.Println(now) //2023-01-15 17:18:00.1687094 +0800 CST m=+0.002955901
//自己构造一个带时区的时间
t := time.Date(2023, 1, 15, 10, 0, 0, 0, time.UTC)
t2 := time.Date(2023, 1, 15, 23, 59, 59, 59, time.UTC)
fmt.Println(t) //2023-01-15 10:00:00 +0000 UTC
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) //2023 January 15 10 0
//格式化时间,这个格式是固定的,不同于其他语言的MM-XX-AA啥的,他是固定时间:2006-01-02 15:04:05
fmt.Println(t.Format("2006-01-02 15:04:05")) //2023-01-15 10:00:00
diff := t2.Sub(t) //Sub:对两个时间做一个减法(计算时间差)
fmt.Println(diff) //13h59m59.000000059s
fmt.Println(diff.Minutes(), diff.Seconds()) //839.9833333343166 50399.000000059
t3, err := time.Parse("2006-01-02 15:04:05", "2023-01-15 10:00:00")
if err != nil {
panic(err)
}
fmt.Println(t3 == t) //true
fmt.Println(now.Unix()) //1673774280 当前的时间戳
}
2-19基础语法 - 数字解析
strconv包是 Go 语言标准库中用于字符串与数字之间转换的包。它提供了许多函数来实现字符串和整数、浮点数、布尔值之间的转换一些常用的函数如下:
strconv.ParseFloat(s string, bitSize int) (float64, error): 将字符串转换为浮点数strconv.ParseInt:将字符串类型转换为整型strconv.Atoi(s string) (int, error): 将字符串转换为整数strconv.Itoa(i int) string: 将整数转换为字符串strconv.FormatFloat(f float64, fmt byte, prec int, bitSize int) string: 将浮点数转换为字符串strconv.ParseBool(s string) (bool, error): 将字符串转换为布尔值
package main
import (
"fmt"
"strconv"
)
func main() {
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) //1.234
n, _ := strconv.ParseInt("111", 10, 64)//字符串 10进制(0则自动推测) 64位进度整数
fmt.Println(n) //111
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n) //4096
n2, _ := strconv.Atoi("123")//字符串转数字。还有将数字转为字符串的方式,写在上面常用中
fmt.Println(n2) //123
n2, err := strconv.Atoi("AAA")//输入不合法则返回错误
fmt.Println(n2, err) //0 strconv.Atoi: parsing "AAA": invalid syntax
}
2-20基础语法 - 进程信息
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
fmt.Println(os.Args)//印了当前程序的命令行参数,os.Args是一个字符串切片,表示程序启动时传入的命令行参数
//使用os.Getenv("PATH")获取环境变量PATH的值,使用os.Setenv("AA", "BB")设置环境变量AA的值为BB
fmt.Println(os.Getenv("PATH"))
fmt.Println(os.Setenv("AA", "BB"))
//快速启动子进程,并且获取其输入输出
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
//如果子进程执行失败,CombinedOutput()函数会返回一个错误,这里使用了panic(err)来处理错误。
panic(err)
}
fmt.Println(string(buf))
}