Golang学习之路3-基础认识(下)

@


前言

学习一门语言,先认识下Golang的基础语法,例如变量定义、数据类型等等。


一、数组

1.定长数组

1)定长数组 (5容量)
nums := [5]string{"aa", "bb", "cc"}
2)遍历数组,方式一
3)遍历数组,方式二 (常用)

package main

import "fmt"

func main1() {
	// 定长数组 (5容量)
	names := [5]string{"aa", "bb", "cc"}
	names[3] = "dd"

	// 遍历数组,方式一
	for i := 0; i < len(names); i++ {
		fmt.Println(names[i])
	}

	// 遍历数组,方式二 (常用)
	for key, value := range names {
	// 可忽略key使用下划线如:for _, value := range names {
		fmt.Println(key, value)
	}
	// 忽略两个需要用=而不能使用:= 如:for _, _ = range names
}

在这里插入图片描述

2.不定长数组

1)不定长数组:

names := []string{"aa", "bb", "cc"}

2)追加数据重新赋值会给自己
cap:查看容量,如果容量不足,会动态扩充容量正常是当前容量的2倍

names = append(names, "dd")

3) 数组切片,左闭右开

// 打印 0-1 索引的数据
fmt.Println(names[:2])
// 打印 1-2 索引的数据
fmt.Println(names[1:3])
// 打印 2-n 索引的数据
fmt.Println(names[2:])

4)创建指定长度及指定容量的数组

// 创建指定长度及指定容量的数组
names2 := make([]string, 10, 50)
names2[0] = "a"

5)如果数组切片赋值,不共享数据则使用:copy

// 基于以上,如果不共享数据则使用:copy
namesList := []string{"aa", "bb"}
copyList := make([]string, 2, 50)
copy(copyList, namesList)
fmt.Println("修改前:", namesList, copyList)
namesList[0] = "cc"
fmt.Println("修改后:", namesList, copyList)

在这里插入图片描述
完整代码:

package main

import "fmt"

func main() {
	// 不定长数组
	names := []string{"aa", "bb", "cc"}
	fmt.Println("追加前的容量:", cap(names))
	// 追加数据重新赋值会给自己
	names = append(names, "dd")
	fmt.Println("追加后的容量:", cap(names))

	// 数组切片&创建新数组,左闭右开
	names1 := names[:2] // 建新数组,数据共享的
	fmt.Println(names1)
	names[0] = "修改后的"
	fmt.Println(names1)
	names = append(names, "追加数据不共享AA")
	fmt.Println(names, names1)

	// 基于以上,如果不共享数据则使用:copy
	namesList := []string{"aa", "bb"}
	copyList := make([]string, 2, 50)
	copy(copyList, namesList)
	fmt.Println("修改前:", namesList, copyList)
	namesList[0] = "cc"
	fmt.Println("修改后:", namesList, copyList)

	// 创建指定长度及指定容量的数组
	names2 := make([]string, 10, 50)
	names2[0] = "a"
}

二、map

map 一种无序的键值对, 它是数据结构 hash 表的一种实现方式。map工作方式就是:定义键和值(key、value),并且可以获取,设置和删除其中的值。

1.使用关键字 map 来声明

names := map[string]string{"key": "value"}

// 使用关键字 map 来声明
names := map[string]string{"ppl": "yes", "gsxl": "no"}
for key, value := range names {
	fmt.Println(key, value)
}

2.使用 make 来声明

// 使用make来声明
mapAge := make(map[string]int)

3.添加元素

// 赋值:key=ppl value=18
mapAge["ppl"] = 18

4.检索key的value是否存在

检索不到默认返回0

// 检索key的value
age, ok := mapAge["ppl"]
if ok {
	fmt.Println("age:", age)
}
// 检索不到返回0
age, ok := mapAge["ppl1"]

5.删除元素

函数没有返回值

// 删除map的key:value,不存在也不会报错,存在则删除
delete(names, "gsxl")
fmt.Println(names)

6.遍历map

for key, value := range names {}

names := map[string]string{"ppl": "yes", "gsxl": "no"}
for key, value := range names {
	fmt.Println(key, value)
}

7.map的注意点

  • map是引用类型,当map赋值给一个新变量指针是指向同一个内部数据结构,因此任一改变另一跟随改变
  • 须指定 key, value 的类型,且数据类型必须与定义一致
  • 无序性,key唯一性
  • value可以为任意类型
  • key可以为基础数据类型(例如 bool, 数字类型,字符串), 不能为数组,切片,map,它的取值必须是能够使用 == 进行比较
  • 线程不安全, 写入并发时(goroutine)需要加锁,另外也不能并发的读写,否则错误

完整代码:

package main

import "fmt"

func main() {

	// 使用关键字 map 来声明
	names := map[string]string{"ppl": "yes", "gsxl": "no"}
	for key, value := range names {
		fmt.Println(key, value)
	}

	// 使用make来声明
	mapAge := make(map[string]int)
	// 赋值:key=ppl value=18
	mapAge["ppl"] = 18

	// 检索key的value
	age, ok := mapAge["ppl1"]
	if ok == false {
		fmt.Println("age:", age)
	}

	// 删除map的key:value
	delete(names, "gsxl")
	fmt.Println(names)
}

在这里插入图片描述

三、指针

什么是指针?
一个指针变量指向了一个值的内存地址,内部垃圾回收机制(gc)。

1.使用指针& 及 *

  • 变量指针存储地址:&name
  • 使用指针访问值:*ptr
// 声明实际变量
name := "ppl"
// 声明指针变量且存储地址=&name
ptr := &name
fmt.Println("name:", name)
fmt.Println("name ptr:", ptr)
fmt.Println("name ptr使用指针访问值:", *ptr)

2.空指针

空指针:nil,既空值如Python的None,mysql的null

// 空指针:nil,既空值如Python的None,mysql的null
var ptrNil *string
// 指针做判断 != 与 ==
if ptrNil == nil {
	fmt.Println("ptrNil:", ptrNil)
}

完整代码

package main

import "fmt"

func main() {
	// 声明实际变量
	name := "ppl"
	// 声明指针变量且存储地址=&name
	ptr := &name
	fmt.Println("name:", name)
	fmt.Println("name ptr:", ptr)
	fmt.Println("name ptr使用指针访问值:", *ptr)

	// 使用new关键字定义
	name1 := new(string)
	*name1 = "ppl"
	fmt.Println(name1)
	fmt.Println(*name1)
	fmt.Println("strPtr():", strPtr(*name1))

	// 空指针:nil,既空值如Python的None,mysql的null
	var ptrNil *string
	// 指针做判断 != 与 ==
	if ptrNil == nil {
		fmt.Println("ptrNil:", ptrNil)
	}
}

func strPtr(str string) *string {
	// 返回 string 的指针
	return &str
}


四、循环与条件判断

1.循环

1.1 for循环
for循环是go语言唯一能使用的循环语句,其它语言还会存在 while 循环...

func main() {
	// for循环
	for i := 0; i < 5; i++ {
		fmt.Println(i)
	}
}

1.2break语句
结束当前整个for循环,多个for循环时便是结束当前for循环代码块

func main() {
	// for循环
	for i := 0; i < 5; i++ {
		fmt.Println("i:", i)
		// break结束循环
		if i == 2 {
			break
		}
	}
}

1.3continue语句
仅跳过本次循环,继续下次循环

func main() {
	// for循环
	for i := 0; i < 5; i++ {
		// continue跳过当前循环,继续下次循环
		if i == 1 {
			fmt.Println("continue进入下次循环,不在执行下面代码")
			continue
		}
	}
}

完整代码:

package main

import "fmt"

func main() {
	// for循环
	for i := 0; i < 5; i++ {
		// 仅跳过本次循环,继续下次循环
		if i == 1 {
			fmt.Println("continue进入下次循环,不在执行下面代码")
			continue
		}
		fmt.Println("i:", i)
		// break结束循环
		if i == 2 {
			break
		}

		for j := 0; j < 5; j++ {
			if j == 0 {
				fmt.Println("跳出嵌套的for循环代码块")
				break
			}
			fmt.Println("被上面break,下面条件永远不可能满足...")
		}
	}
}

在这里插入图片描述

2.条件判断

if是一个具有布尔条件的语句,如果该条件为真,则执行第一个代码块。如果条件求值为false,则执行另一个else块。
1.条件判断 if else

// 条件判断 if else
age := 18
if age >= 18 { // age >=18 为条件
	fmt.Println("age is >= 18")
} else {
	fmt.Println("age is < 18")
}

2.且与或

  • &&:且,需要同时满足条件
  • ||:或,满足其中一个条件即可
age := 18
// &&:且,需要同时满足条件
if age > 16 && age < 20 {
	fmt.Println("ge > 16 且 age < 20, result age is:", age)
} else if age > 22 {
	fmt.Println("age is >22")
} else {
	fmt.Println("age is <16 or > 22")
}
// ||:或,满足其中一个条件即可
if age > 20 || age == 18 {
	fmt.Println("age is >20 or ==18")
}

3.switch条件语句
1)switch条件语句,匹配后默认break(可写多个条件)

// switch条件语句,匹配后默认break(可写多个条件)
number := 18
switch number {
case 12, 13:
	fmt.Println("The is 12, 13")
case 18:
	fmt.Println("The is 18")
default:
	fmt.Println("The is default")
}

2)switch还可以使用类似 if else

// switch还可以使用类似 if else
switch {
case number >= 16 && number <= 25:
	fmt.Println("The is >=16 and <=25")
default:
	fmt.Println("switch default")
}

完整代码:

package main

import "fmt"

func main() {
	// 条件判断 if else
	age := 18
	if age >= 18 { // age >=18 为条件
		fmt.Println("age is >= 18")
	} else {
		fmt.Println("age is < 18")
	}

	// &&:且,需要同时满足条件
	if age > 16 && age < 20 {
		fmt.Println("ge > 16 且 age < 20, result age is:", age)
	} else if age > 22 {
		fmt.Println("age is >22")
	} else {
		fmt.Println("age is <16 or > 22")
	}

	// ||:或,满足其中一个条件即可
	if age > 20 || age == 18 {
		fmt.Println("age is >20 or ==18")
	}

	// 常用判断满足直接返回值,避免使用else
	num := 19
	if num%2 == 0 {
		fmt.Println(num, "is even")
		return
	}
	fmt.Println(num, "is odd")

	// switch条件语句,匹配后默认break(可写多个条件)
	number := 18
	switch number {
	case 12, 13:
		fmt.Println("The is 12, 13")
	case 18:
		fmt.Println("The is 18")
	default:
		fmt.Println("The is default")
	}
	// switch还可以使用类似 if else
	switch {
	case number >= 16 && number <= 25:
		fmt.Println("The is >=16 and <=25")
	default:
		fmt.Println("switch default")
	}
	checkType(1)
}

func checkType(i interface{}) {
	switch v := i.(type) {
	case string:
		fmt.Println(v, "is string")
	case int:
		fmt.Println(v, "is int")
	default:
		fmt.Println(v, "is other")
	}
}

在这里插入图片描述
End

posted @ 2022-11-06 19:44  广深-小龙  阅读(40)  评论(0编辑  收藏  举报