开发环境
下载安装
网址:go.dev/
直接根据需要下载即可
配置集成开发环境
vscode 下载go插件
goland 付费软件
基础语法
代码
package main //表示程序的入口包、入口文件
import (
"fmt" //输入输出字符串
)//导入格式包
//或者
//import "fmt"
func main() {
fmt.Println("hello world")
} //main函数
编译运行
go build +文件路径 //编译
go run +文件路径(举例:/workspace/go-by-example/example/01-hello) //运行
变量申明
方法一
var a = "initial"
//格式:var name= value ,这会自动推导格式类型
var b, c int = 1, 2
//也可以显式说明变量类型
方法二
f := float32(e)
//格式: 变量名 := 值
常量
//go会自动确定常量的类型
const s string = "constant"
const h = 500000000
const i = 3e20 / h
//格式: const 常量名 =值
if-else
//if后面没有括号
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
循环
//只有for循环
//for后面没有括号
//有break(退出)和continue(继续)
for j := 7; j < 9; j++ {
fmt.Println(j)
}
switch
//不需要再每一个case后面加上break
//可以使用不同的类型,甚至是结构体
switch a {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
case 4, 5:
fmt.Println("four or five")
default:
fmt.Println("other")
}
//也可以代替if-else
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
数组
//长度固定
//一维整型数组
var a [5]int
a[4] = 100
//定义时确定数组内容
b := [5]int{1, 2, 3, 4, 5}
good := []string{"g", "o", "o", "d"}
fmt.Println(b)
//二维数组
var twoD [2][3]int
for i := 0; i < 2; i++ {
for j := 0; j < 3; j++ {
twoD[i][j] = i + j
}
}
切片
//可变长度数组
//make创建切片
s := make([]string, 3)
//append添加元素,必须要赋值回去
s = append(s, "d")
//copy复制
copy(c, s)
//获取元素
fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5]) // [a b c d e]
fmt.Println(s[2:]) // [c d e f]
map
//make创建空map,make(map[key的类型]value的类型)
m := make(map[string]int)
//创建已知内容切片
m2 := map[string]int{"one": 1, "two": 2}
//写入
m["two"] = 2
//读取
fmt.Println(m["one"])
//删除
delete(m, "one")
//读取时,ok判断是否有key存在
r, ok := m["unknow"]
fmt.Println(r, ok) // 0 false
range
//遍历数组时:索引 值
for i, num := range nums {
sum += num
if num == 2 {
fmt.Println("index:", i, "num:", num) // index: 0 num: 2
}
}
//遍历map时:key value
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
for k := range m {
fmt.Println("key", k) // key a; key b
}
函数
//两种方式
func add(a int, b int) int {
return a + b
}
func add2(a, b int) int {
return a + b
}
//第一个返回值,第二个返回信息
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
指针
//对传入参数修改
func add2(n int) {
n += 2
}//传入的参数是拷贝
func add2ptr(n *int) {
*n += 2//运算时加*
}
func main() {
n := 5
add2(n)
fmt.Println(n) // 5
add2ptr(&n)//需要调用&
fmt.Println(n) // 7
}
结构体
//定义
type user struct {
name string
password string
}
//初始化时需要传入初始值,默认是空值
a := user{name: "wang", password: "1024"}
//定义
var d user
//调用参数
d.name = "wang"
d.password = "1024"
func checkPassword(u user, password string) bool {
return u.password == password
}
//使用指针可以减少大结构体拷贝时的开销
func checkPassword2(u *user, password string) bool {
return u.password == password
}
结构体方法
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: "wang", password: "1024"}
a.resetPassword("2048")
fmt.Println(a.checkPassword("2048")) // true
}
错误处理
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name) // wang
字符串操作
a := "hello"
//包含操作
fmt.Println(strings.Contains(a, "ll")) // true
//字符串计数
fmt.Println(strings.Count(a, "l")) // 2
fmt.Println(strings.HasPrefix(a, "he")) // true
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
fmt.Println(len(a)) // 5
字符串格式化
//打印多个变量,并且换行
fmt.Println(s, n)
//%v表示任意类型变量,%+v,%#v输出信息越来越详细
fmt.Printf("s=%v\n", s) // s=hello
fmt.Printf("p=%v\n", p) // p={1 2}
fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}
json
//结构体每个属性字段的第一个字母时大写
type userInfo struct {
Name string
Age int `json:"age"`//字段名变小写
Hobby []string
}
//可以使用json.Marshal进行序列化
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
//反序列化
err = json.Unmarshal(buf, &b)
time
//当前时间
now := time.Now()
//其他时间
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
//时间减法
diff := t2.Sub(t)
//格式为时间字符串
fmt.Println(t.Format("2006-01-02 15:04:05"))
//获取时间详细信息
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute())
//解析时间
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
//时间戳
fmt.Println(now.Unix()) // 1648738080
数字解析
//导入包
"strconv"
//解析字符串
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) // 1.234
//参数依次是数值,进制,返回数值
n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n) // 111
//十进制字符串转化为数字
n2, _ := strconv.Atoi("123")
fmt.Println(n2) // 123
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}
进程信息
//获取命令行参数
// go run example/20-env/main.go a b c d
fmt.Println(os.Args) // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main(临时目录) a b c d]
//获取环境变量
fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
//写入环境变量
fmt.Println(os.Setenv("AA", "BB"))
//快速启动子进程
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()