Go语言快速上手(二) | 青训营笔记

87 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记,非常感谢字节跳动无偿地分享技术知识并细致地讲解指导。本篇笔记主要介绍go语言的基础语法知识

一、输入输出

1) 打印输出

类似于Python,比较简单。

package main

import (
	"fmt"
)

func main() {
	fmt.Println("hello world") //末尾补回车; fmt包的函数
	print("hello world")       //直接打印,不补回车; 新版本go语言内置函数
	println("hello world")     //末尾补回车; 新版本go语言内置函数
}

2) 标准输入

类似于C语言,参数、用法都差不多。

package main

import (
	"fmt"
)

func main() {
	var a int
	fmt.Scanf("%d\n", &a) // 基本就是c语言的scanf
	println("a = ", a)
	fmt.Scanln(&a) // 扫描一行,遇到换行符或EOF就停止
	println("a = ", a)
}

二、变量常量

var表示变量,const表示常量,类型在变量名后面,支持类型推导,还支持简单变量申明。

注意:go语言支持指针,用法与c语言基本一致,“ * ”是指针,“ & ”是取地址。

package main

import (
	"fmt"
	"math"
)

func main() {

	// 标准变量声明
	var a = "initial" // 自动推导类型

	var b, c int = 1, 2 // 显式的给出类型

	var d = true

	var e float64

	// 简短局部变量声明
	f := float32(e)

	g := a + "foo"
	fmt.Println(a, b, c, d, e, f) // initial 1 2 true 0 0
	fmt.Println(g)                // initialfoo

	const s string = "constant"
	const h = 500000000
	const i = 3e20 / h
	fmt.Println(s, h, i, math.Sin(h), math.Sin(i))
}

三、条件语句

格式限制严格,“ if 表达式 { ” 必须在同一行,“ } else { ” 必须在同一行。

package main

import "fmt"

func main() {

	if 7%2 == 0 {
		fmt.Println("7 is even")
	} else {
		fmt.Println("7 is odd")
	}

	if 8%4 == 0 {
		fmt.Println("8 is divisible by 4")
	}

	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关键字,承担while和for的功能。

package main

import "fmt"

func main() {

	i := 1
	for {
		fmt.Println("loop")
		break
	}
	for j := 7; j < 9; j++ {
		fmt.Println(j)
	}

	for n := 0; n < 5; n++ {
		if n%2 == 0 {
			continue
		}
		fmt.Println(n)
	}
	for i <= 3 {
		fmt.Println(i)
		i = i + 1
	}
}

五、分支语句

switch功能与c语言中的switch类似,只是不需要加break就有c语言中加了break的含义。

package main

import (
	"fmt"
	"time"
)

func main() {

	a := 2
	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")
	}

	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("It's before noon")
	default:
		fmt.Println("It's after noon")
	}
}

六、数组与切片

数组,直接在类型前面加上[len]即可,多个[]就是多维数组;[]中没有具体数值时就是一个切片。

切片,类似于python的列表[],就是长度可变的数组。“ var a []int ” 创建长度为0的切片,“ a := make([]int, 3) ” 创建长度为3的切片。

package main

import "fmt"

func main() {

	s := make([]string, 3)
	s[0] = "a"
	s[1] = "b"
	s[2] = "c"
	fmt.Println("get:", s[2])   // c
	fmt.Println("len:", len(s)) // 3

	s = append(s, "d")
	s = append(s, "e", "f")
	fmt.Println(s) // [a b c d e f]

	c := make([]string, len(s))
	copy(c, s)
	fmt.Println(c) // [a b c d e f]

	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]

	good := []string{"g", "o", "o", "d"}
	fmt.Println(good) // [g o o d]
}

七、映射map

类型关键字为“ map[key_type]value_type ”,创建方式类似于切片,可以用var关键字创建,也可用make创建。用法类似于c++的map和python的字典。

package main

import "fmt"

func main() {
	m := make(map[string]int)
	m["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") // 删除one索引和对应的值

	m2 := map[string]int{"one": 1, "two": 2}
	var m3 = map[string]int{"one": 1, "two": 2}
	fmt.Println(m2, m3)
}

八、函数

函数定义格式为:“ func 函数名(参数列表) 返回值类型 { ”,前面的main函数就是标准的无返回值函数。此外,函数参数列表可以简写为如下形式:

func add2(a, b int) int {
	return a + b
}

九、结构体(类)

只有一个struct关键字,没有class关键字;struct中只能定义数据成员,不能定义函数成员。

所有的类成员函数需要定义为如下形式,才能通过 . 操作访问:

type user struct {
	name     string
	password string
}

func (u user) checkPassword(password string) bool {
	return u.password == password
}

十、错误处理

errors包提供错误处理,error是接口类型,是一种只含有未实现的方法的类。可以使用errors.New("not found")来创建一个错误。

PS: go语言有interface关键字,具体用法参见go语言中的interface使用实例_Golang_脚本之家 (jb51.net)

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) // wang

	if u, err := findUser([]user{{"wang", "1024"}}, "li"); err != nil {
		fmt.Println(err) // not found
		return
	} else {
		fmt.Println(u.name)
	}
}