Go语言基础语法 | 青训营笔记

87 阅读10分钟

一.变量

1.变量的声明

//写法一
var a,b int
a,b = 1,2//平行赋值语句

//写法二
var a,b int = 1,2

//写法三
var a,b = 1,2

//写法四
a,b := 1,2

//写法五
a,b := int(1),int(2)

...

其它类型的变量均可这样写

常量的声明

//常量的声明,使用 const
const s string = "constant"//显式

const s = "constant"//隐式

const a,b = 1,2

const (
    Name = "小夏"
    age = 18
    male = true
)

二.if else

if 8%4 == 0 { // 判断8是否可以被4整除
	fmt.Println("8 is divisible by 4") // 如果可以,打印"8 is divisible by 4"
}



if 7%2 == 0 { // 判断7是否为偶数
	fmt.Println("7 is even") // 如果是,打印"7 is even"
} else {
	fmt.Println("7 is odd") // 如果不是,打印"7 is odd"
}



if num := 9; num < 0 { // 定义一个变量num并赋值为9,判断num是否小于0
	fmt.Println(num, "is negative") // 如果是,打印变量num的值以及"is negative"
} else if num < 10 { // 如果num不小于0,判断num是否小于10
	fmt.Println(num, "has 1 digit") // 如果是,打印变量num的值以及"has 1 digit"
} else {
	fmt.Println(num, "has multiplle digits") // 如果不是,打印变量num的值以及"has multiplle digits"
}

三.循环

Go语言中没有 for、while、do while三种循环之分

只有一种循环,就是for循环

// 初始化 i 的值为 1
i := 1
// 无限循环,直到遇到 break 跳出循环
for {
	fmt.Println("loop")
	break
}
// 循环从 7 到 8,输出 j 的值
for j := 7; j < 9; j++ {
	fmt.Println(j)
}

// 循环从 0 到 4,如果 n 是偶数则继续下一次循环,否则输出 n 的值
for n := 0; n < 5; n++ {
	if n%2 == 0 {
		continue
	}
	fmt.Println(n)
}

// 循环条件是 i 小于等于 3,输出 i 的值并将 i 加 1
for i <= 3 {
	fmt.Println(i)
	i = i + 1
}

四.switch

与C++不同的是,不需要加break

// 初始化 a 的值为 2
a := 2
// 根据 a 的值进行分支判断
switch a {
case 1:
	fmt.Println("one")
case 2,3:// 可以将多个值合并到一个分支中,用逗号分隔
	fmt.Println("two or three")
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")
}

五.数组,切片(Slice),Map(Go语言 数组、切片、map的区别-CSDN博客)

类型比较

数组:值类型 切片:引用类型 map:引用类型

语法比较

数组的语法:var name [5]string []必须指定长度数字

var a  [10]int //声明数组

切片的语法:var name []string

var b []int    //声明切片

map的语法:var map变量名 map[key类型]vlaue类型 []中必须指定类型

var c map[string]int   //声明map类型

初始化比较

切片和map是可以被make初始化的,数组不行,数组必须在声明时初始化。 初始化之后才能有内存地址

func main() {
	a := make([]int,5,10)
	b := make(map[string]int,10)
	fmt.Printf("%T\n",a)
	fmt.Printf("%T",b)
}

输出结果:

[]int
map[string]int

另外,new和make都是用于初始化的,它们两个区别在于new只能初始化值类型(int、string等),make只能初始化引用类型(切片、map、channel)

具体部分看CSDN的文章Go语言 数组、切片、map的区别_map和数组的区别_登云时刻的博客-CSDN博客

六.range(Go 语言范围(Range)_go range-CSDN博客)

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。

在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。

for 循环的 range 格式可以对 slice、map、数组、字符串 等进行迭代循环。

格式如下:

for key, value := range oldMap {
    newMap[key] = value
}

以上代码中的 key 和 value 是可以省略。

如果只想读取 key,格式如下:

for key := range oldMap

或者这样:

for key, _ := range oldMap

如果只想读取 value,格式如下:

for _, value := range oldMap

range 关键字在 go 语言中是相当常用好用的语法糖,可以用在 for 循环中迭代 array、slice、map、channel、字符串所有涉及到遍历输出的东西。

七.函数

// add 函数将两个整数相加并返回其结果。
func add(a int, b int) int {
	return a + b
}

// add2 函数与 add 函数相同,但使用了简化的参数语法。
func add2(a, b int) int {
	return a + b
}

// exists 函数检查给定键是否存在于给定的字符串键值对映射中。
// 如果键存在,则返回键的值和 true,否则返回 "" 和 false。
func exists(m map[string]string, k string) (v string, ok bool) {
	v, ok = m[k]
	return v, ok
}

func main() {
	// 调用 add 函数并打印结果。
	res := add(1, 2)
	fmt.Println(res)

	// 调用 exists 函数检查键 "a" 是否存在于 map 中,并打印结果。
	v, ok := exists(map[string]string{"a": "A"}, "a")
	fmt.Println(v, ok)
}

八.指针

// add2 函数接受一个整数并将其加 2,但它不会改变原始参数的值。
func add2(n int) {
	n += 2
}

// add2ptr 函数接受一个指向整数的指针,并将该整数加 2。
// 由于它接受的是指针,因此它可以修改原始参数的值。
func add2ptr(n *int) {
	*n += 2
}

func main() {
	// 创建一个整数变量 n 并初始化为 5。
	n := 5

	// 调用 add2 函数并打印 n 的值。
	add2(n)
	fmt.Println(n) // 输出:5

	// 调用 add2ptr 函数并打印 n 的值。
	// 由于 add2ptr 接受的是指针,它会修改原始参数的值。
	add2ptr(&n)
	fmt.Println(n) // 输出:7
}

九.结构体

// 定义一个名为 user 的结构体,表示用户的信息。
type user struct {
	name     string
	password string
}

func main() {
	// 创建四个 user 变量,并分别使用不同的方式初始化它们的值。
	a := user{name: "wang", password: "1024"} // 使用字段名初始化。
	b := user{"wang", "1024"}                 // 直接使用值初始化,字段顺序必须与结构体定义中的顺序一致。
	c := user{name: "wang"}                   // 仅初始化 name 字段,password 字段将为默认值 ""。
	c.password = "1024"                       // 然后使用赋值语句为 password 字段赋值。
	var d user                                // 声明一个 user 变量,所有字段都将为默认值 ""。
	d.name = "wang"                            // 然后使用赋值语句为两个字段赋值。
	d.password = "1024"

	// 打印这四个变量的值。
	fmt.Println(a, b, c, d)

	// 调用 checkPassword 函数检查密码是否正确,它接受一个 user 参数和一个密码字符串。
	fmt.Println(checkPassword(a, "haha")) // 输出 false,因为密码不匹配。

	// 调用 checkPassword2 函数检查密码是否正确,它接受一个指向 user 的指针和一个密码字符串。
	fmt.Println(checkPassword2(&a, "haha")) // 输出 false,因为密码不匹配。
}

// checkPassword 函数检查给定用户的密码是否匹配,它接受一个 user 参数和一个密码字符串。
func checkPassword(u user, password string) bool {
	return u.password == password
}

// checkPassword2 函数检查给定用户的密码是否匹配,它接受一个指向 user 的指针和一个密码字符串。
func checkPassword2(u *user, password string) bool {
	return u.password == password
}
type user struct {
	name     string
	password string
}

// checkPassword 方法检查给定用户的密码是否匹配,它接受一个 password 参数。
// 它是一个值接收器,因此不会修改 user 的值。
func (u user) checkPassword(password string) bool {
	return u.password == password
}

// resetPassword 方法将给定用户的密码重置为指定的值,它接受一个 password 参数。
// 它是一个指针接收器,因此可以修改 user 的值。
func (u *user) resetPassword(password string) {
	u.password = password
}

func main() {
	// 创建一个 user 变量,并初始化它的值。
	a := user{name: "wang", password: "1024"}

	// 使用 resetPassword 方法将密码重置为新的值。
	a.resetPassword("2048")

	// 使用 checkPassword 方法检查密码是否正确,并输出结果。
	fmt.Println(a.checkPassword("2048")) // 输出 true,因为密码已被重置为 2048。
}

十.错误的处理

type user struct {
	name     string
	password string
}

// findUser 方法接收一个 user 切片和一个 name 字符串,它返回指向找到的用户的指针和一个错误。
// 如果找到了用户,则 err 返回 nil,否则返回错误信息。
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)
		return
	} else {
		fmt.Println(u.name) // 不会被执行,因为 u 是 nil 指针,访问它的 name 属性会导致 panic。
	}
}

十一.字符串

func main() {
	a := "hello"

	// 判断字符串 a 中是否包含 "ll" 子串
	fmt.Println(strings.Contains(a, "ll"))

	// 计算字符串 a 中 "l" 字符出现的次数
	fmt.Println(strings.Count(a, "l"))

	// 判断字符串 a 是否以 "he" 开头
	fmt.Println(strings.HasPrefix(a, "he"))

	// 查找字符串 a 中 "ll" 子串的位置
	fmt.Println(strings.Index(a, "ll"))

	// 将字符串切片 ["he", "llo"] 按照 "-" 连接为一个字符串
	fmt.Println(strings.Join([]string{"he", "llo"}, "-"))

	// 将字符串 a 重复两次
	fmt.Println(strings.Repeat(a, 2))

	// 将字符串 a 中的 "e" 字符替换为 "E",-1 表示替换所有匹配的字符
	fmt.Println(strings.Replace(a, "e", "E", -1))

	// 将字符串 "a-b-c" 按照 "-" 分隔为切片 ["a", "b", "c"]
	fmt.Println(strings.Split("a-b-c", "-"))

	// 将字符串 a 转换为小写字母
	fmt.Println(strings.ToLower(a))

	// 将字符串 a 转换为大写字母
	fmt.Println(strings.ToUpper(a))

	// 计算字符串 a 的长度
	fmt.Println(len(a))

	b := "你好"

	// 计算字符串 b 的长度,UTF-8 编码下一个汉字占用三个字节
	fmt.Println(len(b))
}
type point struct {
    x, y int
}

func main() {
    s := "hello"
    n := 123
    p := point{1, 2}

    // 使用 Println 输出字符串和整数
    fmt.Println(s, n)

    // 使用 Println 输出结构体
    fmt.Println(p)

    // 使用 Printf 输出格式化字符串
    fmt.Printf("s=%v\n", s)
    fmt.Printf("n=%v\n", n)

    // 使用 %+v 输出带字段名的结构体
    fmt.Printf("p=%+v\n", p)

    // 使用 %#v 输出带类型和字段名的结构体
    fmt.Printf("p=%#v\n", p)

    f := 3.141592653

    // 输出浮点数
    fmt.Println(f)

    // 使用格式化字符串输出浮点数,保留 2 位小数
    fmt.Printf("%.2f\n", f)
}

十二.JSON的处理

type userInfo struct {
	Name  string
	Age   int `json:"age"` // 对 Age 字段添加了 tag,用于指定 JSON 编码和解码时对应的字段名
	Hobby []string
}

func main() {
	a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}

	// 将 struct 转换为 JSON 字节数组
	buf, err := json.Marshal(a)
	if err != nil {
		panic(err)
	}
	fmt.Println(buf)              // [123 34 78 97 109 ... 34 93 125]
	fmt.Println(string(buf))      // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}

	// 将 struct 转换为格式化后的 JSON 字节数组
	buf, err = json.MarshalIndent(a, "", "\t")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf))
	// {
	// 	"Name": "wang",
	// 	"age": 18,
	// 	"Hobby": [
	// 		"Golang",
	// 		"TypeScript"
	// 	]
	// }

	// 将 JSON 字节数组转换为 struct
	var b userInfo
	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"}}
}

十三.时间

func main() {
    now := time.Now()  // 获取当前时间
    fmt.Println(now)   // 打印当前时间
    t := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.UTC)  // 创建一个时间对象,与 now 时间只差秒以下部分
    t2 := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), 0, time.UTC)  // 创建另一个时间对象,与 now 时间只差秒以下部分
    fmt.Println(t)  // 打印 t
    fmt.Println(now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())  // 打印 now 的年月日时分秒
    fmt.Println(t.Format("2004-06-20 13:50:02"))  // 格式化输出 t
    diff := t2.Sub(t)  // 计算 t2 与 t 之间的时间差
    fmt.Println(diff)  // 打印时间差
    fmt.Println(diff.Minutes(), diff.Seconds())  // 打印时间差的分钟数和秒数
    t3, err := time.Parse("2004-06-20 13:50:02", "2023-05-14 15:29:04")  // 解析时间字符串,得到一个时间对象
    if err != nil {
        panic(err)
    }
    fmt.Println(t3 == t)  // 判断 t3 是否等于 t
    fmt.Println(now.Unix())  // 获取当前时间的 Unix 时间戳
}

十四.数字解析

func main() {
	//将字符串 "1.234" 转换成 float64 类型的浮点数
	f, _ := strconv.ParseFloat("1.234", 64)
	fmt.Println(f) //1.234

	//将字符串 "111" 转换成 int64 类型的整数
	n, _ := strconv.ParseInt("111", 10, 64)
	fmt.Println(n) //111

	//将字符串 "0x1000" 转换成 int64 类型的整数,0 表示自动判断进制
	n, _ = strconv.ParseInt("0x1000", 0, 64)
	fmt.Println(n) //4096

	//将字符串 "123" 转换成 int 类型的整数
	n2, _ := strconv.Atoi("123")
	fmt.Println(n2) //123

	//将字符串 "AAA" 转换成 int 类型的整数,由于 "AAA" 不是合法的整数字符串,会返回解析错误
	n2, err := strconv.Atoi("AAA")
	fmt.Println(n2, err)//0 strconv.Atoi: parsing "AAA": invalid syntax
}

十五.进程信息

func main() {
	fmt.Println(os.Args) // 打印命令行参数

	fmt.Println(os.Getenv("PATH")) // 打印 PATH 环境变量
	fmt.Println(os.Setenv("AA", "BB")) // 设置环境变量 AA 的值为 BB

	buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput() // 执行 grep 命令查找 /etc/hosts 中包含 "127.0.0.1" 的行
	if err != nil {
		panic(err)
	}
	fmt.Println(string(buf)) // 打印 grep 命令输出的结果
}