Go语言基础
重点语法以及与C/C++区别
Hello World
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
变量类型
string
, int
, bool
, float64
, float32
等,优先级与 C/C++ 类似
- 字符串是内置类型,可以直接用
+
拼接
变量声明
var a = "strings"
var b int = 1
c := b
常量
const d string = "constant"
条件语句
if condition {
} else {
}
if num := 9; num < 0 {
}
循环语句
for {
}
for i := 1; i < 10; i++ {
}
选择语句
switch a {
case 1:
case 2, 3:
default:
}
t := 1
switch {
case t * 2 < 20:
}
数组
var a [5]int
b := [5]int{1, 2, 3, 4, 5}
var c [2][3]int
fmt.Println(c)
切片
s := make([]string, 3)
s = append(s, "d", "e")
new_s := make([]string, len(s))
copy(new_s, s)
s[2:5]
s[:5]
s[2:]
fmt.Println(s)
map
m := make(map[key_type]value_type)
m2 := map[string]int{"one": 1, "two": 2}
var m3 = map[string]int{"one": 1, "two": 2}
m["one"] = 1
delete(m, "one")
v, ok := m["unknow"]
fmt.Println(v, ok)
range
nums := []int{2, 3, 4}
for index, num := range nums {
}
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v)
}
for k := range m {
fmt.Println("key", k)
}
函数
func add(a int, b int) int {
}
func add2(a, b int) int {
}
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
指针
- 与C/C++类似,不过
*
是写在前面,如func add(n *int)
- 取值时用
*
取值,如*n += 2
- 传参时仍然用
&
取地址
结构体
- 结构体的定义与使用
- 语法与C语言类似,不过声明变量时先写变量名再写结构体的名字
- 可以使用
:=
直接在声明时初始化结构体变量
- 结构体可以作为函数的参数,也能传入地址,但是指针的访问不是
->
,还是.
type user struct {
name string
pswd string
}
a := user{name: "wang", password: "1024"}
b := user{"wang", "1024"}
c := user{name: "wang"}
c.password = "1024"
var d user
d.name = "wang"
d.password = "1024"
fmt.Println(a, b, c, d)
func checkPassword2(u *user, password string) bool {
return u.password == password
}
- 结构体方法
- 结构体方法是在函数名前面加上
(结构体变量名 结构体名)
- 结构体方法的结构体变量名也能传入指针
- 直接通过
结构体变量名.结构体方法名
使用结构体方法
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: "wang", password: "1024"}
a.resetPassword("2048")
fmt.Println(a.checkPassword("2048"))
}
错误处理
- 错误处理需要引入
errors
模块
- 返回值增加一个
error
类型的错误变量
- 没有错误时
error
变量返回nil
- 有错误时
error
变量返回错误信息errors.New("错误信息")
- 可以直接
fmt.Println()
打印error
类型的变量
package main
import (
"errors"
"fmt"
)
type user struct {
name string
password string
}
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")
}
func main() {
u, err := findUser([]user{{"wang", "1024"}}, "wang")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(u.name)
if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
fmt.Println(err)
return
} else {
fmt.Println(u.name)
}
}
字符串及格式化
- 字符串基本操作函数
- 需要引入
strings
模块
- 使用
strings.方法名
fmt.Println(strings.Contains(a, "ll")) 字符串是否包含
fmt.Println(strings.Count(a, "l")) 字符串计数
fmt.Println(strings.HasPrefix(a, "he")) 字符串是否包含前缀
fmt.Println(strings.HasSuffix(a, "llo")) 字符串是否包含后缀
fmt.Println(strings.Index(a, "ll")) 定位子串位置
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) 链接字符串
fmt.Println(strings.Repeat(a, 2)) 重复字符串
fmt.Println(strings.Replace(a, "e", "E", -1)) 字符串替换,第四个变量是要替换的次数,-1 将字符串 s 中的所有的 old 替换成 new
fmt.Println(strings.Split("a-b-c", "-")) 字符串分割
fmt.Println(strings.ToLower(a)) 将字符串变为小写字符
fmt.Println(strings.ToUpper(a)) 将字符串变为大写字符
fmt.Println(len(a)) len函数计算字符串长度,中文字符长度不为1
- 字符串格式化
- 使用
fmt
模块格式化打印字符串
fmt.Println()
可以直接打印变量
fmt.Printf()
类似于C语言的打印函数,不过%v
可以表示所有类型的变量
%+v
比较详细的打印变量的内容
%#v
更加详细的打印变量的结构和内容
- 此外,也能够用
%.2f
等格式
type point struct {
x, y int
}
p := point{1, 2}
fmt.Printf("p=%v\n", p)
fmt.Printf("p=%+v\n", p)
fmt.Printf("p=%#v\n", p)
Json文件处理
- 使用
encoding/json
模块
- 定义结构体时变量名首字母需要大写
- 定义结构体时使用
json:"name"
标签指定在 JSON 编码和解码时使用的字段名称
json.Marshal()
将数据结构序列化成json字符串
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
将数据结构转换为 JSON 字符串,并进行美化格式化输出,通过json.MarshalIndent()
调用,参数 v
是要转换为 JSON 字符串的数据结构,prefix
是每行前面添加的前缀字符串,indent
是用于缩进的字符串
- 序列化后的json字符串使用
string()
转换打印
- 序列化后的json字符串通过
json.Unmarshal()
反序列化到一个空的变量中
package main
import (
"encoding/json"
"fmt"
)
type userInfo struct {
Name string
Age int `json:"age"`
Hobby []string
}
func main() {
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
if err != nil {
panic(err)
}
fmt.Println(buf)
fmt.Println(string(buf))
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
err = json.Unmarshal()(buf, &b)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b)
}
时间处理
- 需要引入
time
模块
- 通过
time.Now()
获取当前时间
- 通过
time.Date()
构建时间变量
- 时间变量有
.Year(), .Month(), .Day(), .Hour(), .Minute()
方法
- 时间变量的
.Format()
方法可以指定格式格式化时间变量
- 时间变量的
.sub()
方法可以对时间变量和另一个时间变量作差
- 时间变量的
.Minutes(), .Seconds()
方法可以将时间变量转换为以分钟或秒数为单位
- 通过
time.Parse()
将指定的字符串解析为时间,2006-01-02 15:04:05
是time模块标准样板,同时该函数会返回错误信息
- 通过
now.Unix()
可以获取当前系统时间戳
func main() {
now := time.Now()
fmt.Println(now)
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
fmt.Println(t)
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute())
fmt.Println(t.Format("2006-01-02 15:04:05"))
diff := t2.Sub(t)
fmt.Println(diff)
fmt.Println(diff.Minutes(), diff.Seconds())
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
if err != nil {
panic(err)
}
fmt.Println(t3 == t)
fmt.Println(now.Unix())
}
数字解析
- 需要引入
strconv
模块
strconv.ParseFloat
将字符串解析为浮点数,第二个参数是精度
strconv.ParseInt
将字符串解析为整数,第二个参数是进制,0表示自动推断,第三个参数是精度
strconv.Atoi
将字符串转为数字,strconv.itoA
将数字转为字符串,如果字符串不合法会返回相应的错误信息
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f)
n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n)
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n)
n2, _ := strconv.Atoi("123")
fmt.Println(n2)
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err)
进程信息
- 需要引入
os
和os/exec
模块
os.Args
获取命令行参数,第一个值是当前程序二进制的位置
os.Getenv()
获取环境变量
os.Setenv()
设置环境变量
exec.Command()
创建了一个命令对象,该命令对象表示要执行的命令,调用 CombinedOutput
方法执行命令并返回命令的标准输出和错误输出合并后的结果
fmt.Println(os.Args)
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 {
panic(err)
}
fmt.Println(string(buf))