参考资料:
切片
slice := make([]int, 5)
完整实践:
package main
import "fmt"
func slice(s[]int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
//切片详情
func main(){
/*
var test_ar = [3]int{1,3,2}
fmt.Print(test_ar)
s := test_ar[1:3]
//对数组test_ar进行切片
var s = []int{4,3,2,1}
//切片的一种声明方式
s := []int{5,4,3,2}
//切片的另一种声明方式
fmt.Print(s)
*/
/*
var a = [6]int{1,2,3,4,5,6}
s := a[:]
slice(s)
s = s[:2]
slice(s)
s = s[2:]
slice(s)
fmt.Print(a)
*/
/*
var s = []int
//这种切片声明方式没有指定切片的容量和长度,会使该切片无法使用。默认值为nil
//长度为0的切片称之为空切片
s = append(s, 32)
//如果要使用必须使用append扩充容量
slice(s)
s := make([]int, 2, 5)
//使用make关键词创建切片
*/
//...三个点是展开切片元素:
s1 := []int{1,2,3,4,5}
s2 := []int{44, 55, 66, 77}
s := append(s1, s2...)
fmt.Println(s)
//append练习
add()
//实现队列应用
msg()
//实现堆栈应用
stack()
}
func stack(){
//应用场景:堆栈 FILO先进后出
//生成栈
stack1 := []int{}
//堆栈input
stack1 = append(stack1, 1, 2, 3, 4, 5)
fmt.Println(stack1) //查看队列完整信息
//获取栈底
data := stack1[(len(stack1)-1)]
fmt.Println(data) //输出信息
//删除栈底
stack1 = stack1[:(len(stack1)-1)]
fmt.Println(stack1) //查看队列完整信息
}
func msg(){
//应用场景:队列 FIFO先进先出
//生成队列
qun1 := []int{}
//写入队列input
qun1 = append(qun1, 1, 2, 3, 4, 5)
fmt.Println(qun1) //查看队列完整信息
//获取队列数据
data := qun1[0]
fmt.Println(data) //输出信息
//删除此队列 output
qun1 = qun1[1:]
fmt.Println(qun1) //查看队列完整信息
}
func add(){
s := make([]int, 5)
s1 := s
//s = []int{1, 2, 3, 4, 5}
fmt.Printf("切片s长度%v,地址%p\n", len(s), s)
fmt.Printf("切片s1长度%v,地址%p\n", len(s1), s1)
s = append(s, 23)
//使用append追加元素后,原始切片数组地址也会发生改变。
//当原始的地址发生改变后,已经和之前地址关联的切片,将不会和新切片地址保持引用关系。
fmt.Printf("切片s长度%v,地址%p\n", len(s), s)
fmt.Printf("切片s1长度%v,地址%p\n", len(s1), s1)
//append不是依据追加的元素个数扩容的,而是依 据原切片的原始容量来计算。
//扩容的算法大概是:若容量较小(小于1K)则成倍扩容,若容量较大(大于1k)则扩容特定长度。
}
输出:
[1 2 3 4 5 44 55 66 77]
切片s长度5,地址0xc0000ca060
切片s1长度5,地址0xc0000ca060
切片s长度6,地址0xc0000a60a0
切片s1长度5,地址0xc0000ca060
[1 2 3 4 5]
1
[2 3 4 5]
[1 2 3 4 5]
5
[1 2 3 4]
Process finished with exit code 0
指针
var i *int
一种存储内存地址的数据类型
package main
import "fmt"
func main() {
num := 255
fmt.Println("num 的内存地址位:", &num)
//使用&关键词表达在内存中的地址
var num_s *int
//声明一个int类型的指针变量num_s
num_s = &num
fmt.Printf("%v address: %v\n", num, num_s)
fmt.Println("指针num_s的值为:", *num_s)
//解引用使用*关键词表示
*num_s++
//解引用并自相加
fmt.Println(num_s, num)
p := &num_s
//把一个整数型指针变量赋值到p
fmt.Println(**p)
//多级指针类型
//整数型指针变量也是一个变量,也可以获取其内存地址到一个新的指针类型中,使用**即可解多级指针类型获取到源值
// new 创建指针new(T) 指针类型T
//new()实例化,会创建存储空间,并返回其地址。
ap := new(int)
ap = &num
fmt.Println(ap)
//空指针,没有指向内存地址的指针被称为空指针。使用nil表示
var bp *int //仅初始化,并没有赋值默认为零值nil
fmt.Printf("%T\n%v", bp, bp)
}
输出:
num 的内存地址位: 0xc00000a0a0
255 address: 0xc00000a0a0
指针num_s的值为: 255
0xc00000a0a0 256
256
0xc00000a0a0
*int
<nil>
Process finished with exit code 0
结构体
type a_server stucr{}
##结构体 是一种自定义数据类型##
package main
import (
"fmt"
)
func main() {
type server struct {
PlayerName string
PlayerNum int
World string
}
//定义一个server类型的结构体
//type定义类型关键词
//struct结构体关键词
var s1_15 = server{
PlayerName: "LIU_MC",
PlayerNum: 1,
World: "DIM1",
}
//为server结构体赋值
var c1_15 = server{
"CCCP",
2,
"END",
}
//赋值如果不写成员变量名,必须按照定义顺序给全部成员变量一个初始值
fmt.Println(s1_15, c1_15)
fmt.Println(c1_15.PlayerName)
//访问结构体成员变量使用点.关键符号 和访问包函数一样
s3 := c1_15
c1_15.PlayerName = "tcxjj"
fmt.Println(c1_15.PlayerName, s3.PlayerName)
//结构体是值类型,非引用类型,所以结构体的空值不是nil,而且当原结构体被更改后这个结构体不会变更数据
temp := struct {
name string
amount int
}{
"南孚电池",
6,
}
//没有名称的结构体,叫做匿名结构体
//匿名结构体定义时必须初始化数据,匿名结构体一般用作临时数据
fmt.Println(temp)
}
输出:
{LIU_MC 1 DIM1} {CCCP 2 END}
CCCP
tcxjj CCCP
{南孚电池 6}
Process finished with exit code 0
错误处理
err
一种存储错误信息的数据类型
实例演示:
package main
//错误处理
import "fmt"
func count(a, b float32, c string)(float32, error){
var v float32
switch c {
case "+":
v = a + b
case "-":
v = a - b
case "*", "x", "X", "×":
v = a * b
case "/", "÷":
if b <= 0 {
return 0, fmt.Errorf("被除数不能为0或者小于0!%v", b)
}else {
v = a / b
}
case "%":
v = float32(int(a) % int(b))
case "&":
v = float32(int(a) & int(b))
case "|":
v = float32(int(a) | int(b))
case "^":
v = float32(int(a) ^ int(b))
case "<<", "<":
v = float32(int(a) << int(b))
case ">>", ">":
v = float32(int(a) >> int(b))
default:
return 0, fmt.Errorf("未知的运算符%v!\n", c)
}
return v, nil
}
func main() {
var (
one float32
two float32
symbol string
)
for true {
fmt.Println("输入第一个值")
_, err := fmt.Scanln(&one)
if err != nil {
fmt.Printf("错误:%s", err)
continue
}
fmt.Println("请输入运算符号(+加 -减 *乘 /除 %余 按位运算:&与 |或 ^异或 <<左移 >>右移)")
_, err = fmt.Scanln(&symbol)
if err != nil {
fmt.Printf("错误:%s", err)
continue
}
fmt.Println("输入第二个值")
_, err = fmt.Scanln(&two)
if err != nil {
fmt.Printf("错误:%s", err)
continue
}
value, err := count(one, two, symbol)
if err != nil {
fmt.Printf("错误:%v\n", err)
} else {
fmt.Printf("%v %v %v = %v\n", one, symbol, two, value)
}
}
}
输出:
输入第一个值
1
请输入运算符号(+加 -减 *乘 /除 %余 按位运算:&与 |或 ^异或 <<左移 >>右移)
+
输入第二个值
2
1 + 2 = 3
输入第一个值
/
错误:strconv.ParseFloat: parsing "": invalid syntax输入第一个值
错误:unexpected newline输入第一个值
1
请输入运算符号(+加 -减 *乘 /除 %余 按位运算:&与 |或 ^异或 <<左移 >>右移)
1
输入第二个值
1
错误:未知的运算符1!