Go语言入门指南(中)
基础语法
-
指针 Go语言也有类似于C语言的指针,在传入函数时只有指针操作才能更新对应变量。但是Go语言的指针相较于C语言,没有自增操作等运算,这综合了各种语言的指针特性。
func add2ptr(n *int) { *n += 2 } func main() { n := 5 add2ptr(&n) } -
结构体 Go语言也有类似C语言的结构体,可以通过
type name struct {}的形式命名和定义结构体,如下代码主函数中给出了结构体初始化和内容访问示例。type user struct { name string password string } func main() { // initialization 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" } -
结构体方法 在Go语言中,和C++的类成员函数相类似,也存在给结构体定义的函数,称为结构体方法。但是Go语言没有类等一系列概念,只存在结构体。 在定义结构体方法时,函数在结构体外部声明,需要在函数名前带上对应结构体参数,如
(u user),即为结构体方法。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")) } -
异常 Go语言对于异常处理也有较完整的工具链。 对于有异常情况的函数,在声明时一般会附加上一个返回参数作为异常返回参数。正常情况时为该参数传回
nil值,异常时则调用errors.New()等函数创建异常类型变量并返回。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) } -
字符串 Go语言的
strings包含有丰富的字符串处理函数。和C++类似,字符串直接作为一个数据类型,并有丰富的处理工具。 下例涵盖了部分常用函数,注释为对应返回内容。func main() { a := "hello" strings.Contains(a, "ll") // true strings.Count(a, "l") // 2 strings.HasPrefix(a, "he") // true strings.HasSuffix(a, "llo") // true strings.Index(a, "ll") // 2 strings.Join([]string{"he", "llo"}, "-") // he-llo strings.Repeat(a, 2) // hellohello strings.Replace(a, "e", "E", -1) // hEllo strings.Split("a-b-c", "-") // [a b c] strings.ToLower(a) // hello strings.ToUpper(a) // HELLO len(a) // 5 } -
格式化输出 调用
fmt.Printf()函数进行输出,可以实现类似于C语言的输出格式,使用百分号和一个字母组成的转换字符表示格式。如下代码有许多常用转换字符的示例,注释为对应输出内容。 而fmt.Println()函数则以跟%v差不多的方式格式化参数,并在最后添加一个换行符。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} fmt.Printf("s=%v\n", s) // s=hello fmt.Printf("n=%v\n", n) // n=123 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} f := 3.141592653 fmt.Println(f) // 3.141592653 fmt.Printf("%.2f\n", f) // 3.14 } -
jsonjson是一种用于发送和接收结构化信息的标准协议,它主要由encoding/json包支持。 一个json结构体的变量名一般都为大写字母开头,可以在声明后附加json:"name"来将格式化输出的对应变量名改为小写字母。 下方代码展示了json信息的序列化与反序列化,在将对应结构体转换为string类型后,其输出也会带上更多信息。type userInfo struct { Name string Age int `json:"age"` Hobby []string } func main() { a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}} // Serialize buf, err := json.Marshal(a) if err != nil { panic(err) } fmt.Println(buf) // [123 34 78 97...] fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]} buf, err = json.MarshalIndent(a, "", "\t") if err != nil { panic(err) } fmt.Println(string(buf)) // { // "Name": "wang", // "age": 18, // "Hobby": [ // "Golang", // "TypeScript" // ] // } var b userInfo // Deserialize err = json.Unmarshal(buf, &b) if err != nil { panic(err) } fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}} } -
timeGo语言的time包有丰富的与时间相关的方法。 包括获取当前时间,设置日期变量及其格式化,时间减法,时间解析,设置时间戳变量等。func main() { // Now now := time.Now() // Date t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC) t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC) t.Year() // 2022 t.Month() // March t.Day() // 27 t.Hour() // 1 t.Minute() // 25 t.Format("2006-01-02 15:04:05") // 2022-03-27 01:25:36 // Sub diff := t2.Sub(t) diff.Minutes() // 65 diff.Seconds() // 3900 // Parse / Format t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36") // timestamp now.Unix() } -
字符串与数字 在Go语言中,要实现字符串与数字的相互转换及其方便,在
strconv包中有一系列成熟的函数可以调用。 其中,strconv.ParseInt("111", 10, 64)的10代表十进制,64则代表精度。func main() { f, _ := strconv.ParseFloat("1.234", 64) // 1.234 n, _ := strconv.ParseInt("111", 10, 64) // 111 n, _ = strconv.ParseInt("0x1000", 0, 64) // 4096 n2, _ := strconv.Atoi("123") // 123 n2, err := strconv.Atoi("AAA") fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax } -
进程 Go语言的
os包和os/exec包中包含一系列和操作系统交互的方法,并能够开启子进程。 以下代码展示了相关函数使用方法,os.Args为该程序的传入参数切片。func main() { // args fmt.Println(os.Args) // environment fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin... fmt.Println(os.Setenv("AA", "BB")) // subprocess buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput() string(buf) // 127.0.0.1 localhost }