go第二章--变量与数据类型

222 阅读13分钟

变量

变量的定义以及初始化

	var username string
	username = "张三"
	fmt.Println(username) //张三

	var username1 string = "张三"
	fmt.Println(username1) //张三

	var username2 = "张三"
	fmt.Println(username2) //张三

一次定义多个变量

同一种数据类型

	var a1, a2 string
	a1 = "a1"  //a1
	a2 = "a2"  //a2
	fmt.Println(a1, a2)

不同数据类型

	var (
		username4 string
		age       int
		sex       string
	)

	username4 = "张三"
	age = 20
	sex = "男"

	fmt.Println(username4, age, sex)
	var (
		username5 = "张三"
		age2      = 20
	)
	fmt.Println(username5, age2)

短变量声明方式

	a, b, c := 12, 13, "C"
	fmt.Println(a, b, c)
	fmt.Printf("a类型:%T b类型:%T c类型:%T", a, b, c)

匿名变量

func getUserinfo() (string, int) {
	return "zhangsan", 10
}

返回2个值

	var username7, age23 = getUserinfo()
	fmt.Println(username7, age23)

返回一个值报错

	var username7 = getUserinfo()
	fmt.Println(username7)

只想要一个返回值时,可以使用匿名

	var username7, _ = getUserinfo()
	fmt.Println(username7)
	var _, age23 = getUserinfo()
	fmt.Println(age23) //10

常量

不可修改

	const A = "aa"
	A = "BB"
	fmt.Println(A)
	const (
		A = "A"
		B = "B"
	)
	fmt.Println(A, B)
	const (
		n1 = iota
		n2
		n3
		n4
	)
	fmt.Println(n1, n2, n3, n4) //0 1 2 3

整型

	var num int = 10
	num = 22
	fmt.Printf("num=%v 类型%T", num, num) //num=22 类型int

int8的范围演示

	var num1 int8 = 98
	fmt.Printf("num=%v 类型:%T", num1, num1)
	var num2 int8 = 130 //constant 130 overflows int8
	fmt.Printf("num=%v 类型:%T", num2, num2)

	var num int16 = 130
	fmt.Printf("num=%v 类型:%T", num, num)

变量占用的字节数

	var a int8 = 15
	fmt.Println(unsafe.Sizeof(a)) //1个字节

	var b int32 = 15
	fmt.Println(unsafe.Sizeof(b)) // 4个字节

int类型转换

	var a1 int32 = 10
	var a2 int64 = 21

	fmt.Println(int64(a1) + a2) //把a1转换成64位
	fmt.Println(a1 + int32(a2)) //把a2转换成32位

以不同进制的方式输出

	num := 12
   	fmt.Printf("num=%v\n", num) //%v 原样输出  //   num=12

	fmt.Printf("num=%d\n", num) //%d 表示10进制输出 // num=12

	fmt.Printf("num=%b\n", num) //%b 表示二进制输出 // num=1100

	fmt.Printf("num=%o\n", num) //%o 表示八进制输出 //  num=14

	fmt.Printf("num=%x\n", num) //%x 表示16进制输出 //  num=14
    

浮点型

定义float类型

var a float32 = 3.12
fmt.Printf("值:%v--%f,类型%T\n", a, a, a) 
//值:3.12--3.120000,类型float32
fmt.Println(unsafe.Sizeof(a))
//4
var b float64 = 3.12
fmt.Printf("值:%v--%f,类型%T\n", b, b, b)
//值:3.12--3.120000,类型float64
fmt.Println(unsafe.Sizeof(b))
//8

保留小数点后面几位

var c float64 = 3.1415925535
fmt.Printf("%v--%f--%.2f--%.4f", c, c, c, c)
// 3.1415925535--3.141593--3.14--3.1416

精度丢失问题

var f4 float64 = 1129.6
fmt.Println(f4 * 100) //112959.99999999999
m1 := 8.2
m2 := 3.8
fmt.Println(m1 - m2) //4.3999999999999995

int类型转换成float类型

a := 10
b := float64(a)
fmt.Printf("a的类型是%T,b的类型是%T", a, b)
//a的类型是int,b的类型是float64
var a1 float32 = 23.4
a2 := float64(a1)
fmt.Printf("a1的类型是%T,a2的类型是%T", a1, a2)
//a1的类型是float32,a2的类型是float64

float类型转换成int类型 不建议这样做,精度丢失问题

var c1 float32 = 23.45
c2 := int(c1)
fmt.Printf("c2的值:%v  c2的类型:%T", c2, c2)
//c2的值:23  c2的类型:int

bool 布尔

  1. 布尔类型变量的默认值为false。
  2. Go 语言中不允许将整型强制转换为布尔型.
  3. 布尔型无法参与数值运算,也无法与其他类型进行转换
	var flag = true
	fmt.Printf("%v--%T", flag, flag) //true--bool
	var b bool
	fmt.Printf("%v", b) //false

在if里判断

	//正确写法
	var f1 = false
	if f1 { //正确写法
		fmt.Printf("true")
	} else {
		fmt.Printf("false")
	}
    //错误写法
    	var a = 1
	if a { //错误写法
		fmt.Printf("true")
	}

	var s = "this is str"
	if s { //错误写法
		fmt.Printf("true")
	}

不同类型变量的默认值

int型变量的默认值为0

	var i int
	fmt.Printf("%v", i) //0

float型变量的默认值为0

	var f float32
	fmt.Printf("%v", f) //0

string型变量的默认值为空

	var s string
	fmt.Printf("%v", s)
// 布尔类型变量的默认值为false
	// var b bool
	// fmt.Printf("%v", b)

字符串

基本操作

定义string类型

var str1 string = "你好golang"
var str2 = "你好 go"
str3 := "你好golang"

fmt.Printf("%v--%T\n", str1, str1)
fmt.Printf("%v--%T\n", str2, str2)
fmt.Printf("%v--%T\n", str3, str3)

字符串转义符

换行

str1 := "this \nis str" //换行
fmt.Println(str1)
this 
is str

输出反斜杠

str2 := "C:\\Go\\bin" //C:\Go\bin    输出反斜杠
fmt.Println(str2)
str3 := "C:Go\"bin"
fmt.Println(str3)
C:\Go\bin
C:Go"bin

多行字符串

	str1 := `a
	this is str
	this is str
					this is str111
	this is str
	this is str
	`
	fmt.Println(str1)
a
	this is str
	this is str
					this is str111
	this is str
	this is str

字符串方法

len(str) 求长度

var str1 = "aaaa" //长度4
fmt.Println(len(str1)) //4
  • 或者 fmt.Sprintf拼接字符串
str1 := "你好"
str2 := "golang"
str3 := str1 + str2
fmt.Println(str3) //你好golang
str1 := "你好"
str2 := "golang"
str3 := fmt.Sprintf("%v%v", str1, str2)
fmt.Println(str3) //你好golang

strings.Split 分割字符串

var str1 = "123-456-789"
arr := strings.Split(str1, "-")
fmt.Println(arr) //[123 456 789]

strings.join 把切片链接成字符串

arr := []string{"php", "java", "golang"}
str3 := strings.Join(arr, "-")
fmt.Printf("%v - %T", str3, str3)  //php-java-golang - string

判断是否包含

str1 := "this is str"
str2 := "thisxxx"
flag := strings.Contains(str1, str2)
fmt.Println(flag) //false

前缀/后缀判断

str1 := "this is str"
str2 := "this"
flag := strings.HasPrefix(str1, str2)
fmt.Println(flag) //true
str1 := "this is str"
str2 := "str"
flag := strings.HasSuffix(str1, str2)
fmt.Println(flag) //false

strings.Index(),strings.LastIndex() 子串出现的位置 查找不到返回-1

str1 := "this is str"
str2 := "is"
num := strings.Index(str1, str2)
print(num) //返回2 
str1 := "this is str"
str2 := "is"
num := strings.LastIndex(str1, str2)
print(num) //返回5
str1 := "this is str"
str2 := "xxx"
num := strings.Index(str1, str2)
print(num) //-1 查找不到返回-1

byte 和 rune 类型

组成每个字符串的元素叫做“字符”,可以通过遍历字符串元素获得字符。 字符用单引号(’) 包裹起来

字节(byte):是计算机中 数据处理 的基本单位,习惯上用大写 B 来表示,1B(byte,字节) = 8bit(位)

字符是指计算机中使用的字母、数字、字和符号

定义字符

var a = 'a'
var b = 'b'
fmt.Printf("值:%v  类型:%T\n", a, a) //值:97  类型:int32
fmt.Printf("值:%v  类型:%T", b, b)
    
// 值:97  类型:int32
// 值:98  类型:int32

原样输出字符%c

var a = 'a'
fmt.Printf("值:%c  类型:%T", a, a)
// 值:a  类型:int32

定义一个字符串输出字符串里面的字符

var str = "this"
fmt.Printf("值:%v 原样输出%c  类型:%T", str[2], str[2], str[2])

// 值:105 原样输出i  类型:uint8

一个汉子占用 3 个字节 一个字母占用一个字节

var str = "this" //占用4个字节
fmt.Println(len(str)) //4
var str = "你好go"      //8
fmt.Println(len(str)) //8

通过循环输出字符串里面的字符

	s := "你好 golang"
	for i := 0; i < len(s); i++ { //byte
		fmt.Printf("%v(%c)", s[i], s[i])
	}
    //228(ä)189(½)160( )229(å)165(¥)189(½)32( )103(g)111(o)108(l)97(a)110(n)103(g)
	s1 := "你好 golang"
	for _, v := range s1 { //rune
		fmt.Printf("%v(%c) ", v, v)
	}
    //20320(你) 22909(好) 32( ) 103(g) 111(o) 108(l) 97(a) 110(n) 103(g) 

修改字符串

byte只能修改英文 rune能修改英文和中文或者其他复合字符

	s1 := "big"
	byteStr := []byte(s1)
	byteStr[0] = 'p'
	fmt.Println(string(byteStr)) //pig
	s1 := "你好golang" //有中文用rune
	runeStr := []rune(s1)
	runeStr[0] = '大'
	fmt.Println(string(runeStr)) //大好golang

数据类型转换

Go 语言中只有强制类型转换,没有隐式类型转换

数值类型之间的相互转换

数值类型包括:整形和浮点型

整型和整型之间的转换

	var a int8 = 20
	var b int16 = 40
	// fmt.Println(a + b) //报错 nvalid operation: a + b (mismatched types float32 and float64)
	fmt.Println(int16(a) + b) //60

浮点型和浮点型之间的转换

	var a float32 = 20
	var b float64 = 40
	// fmt.Println(a + b) //nvalid operation: a + b (mismatched types float32 and float64)
	fmt.Println(float64(a) + b)

整型和浮点型之间的转换

转换的时候建议从低位转换成高位,高位转换成低位的时候如果转换不成功就会溢出,和我们想的结果不一样。

	var a float32 = 20.23
	var b int = 40
	fmt.Println(a + float32(b)) //60.23

转换成 String 类型

mt.Sprintf()

Sprintf 使用中需要注意转换的格式 int 为%d float 为%f bool 为%t byte 为%c

	var i int = 20
	var f float64 = 12.456
	var t bool = true
	var b byte = 'a'

	str1 := fmt.Sprintf("%d", i)
	fmt.Printf("值:%v 类型:%T\n", str1, str1)
    //值:20 类型:string

	str2 := fmt.Sprintf("%.2f", f)
	fmt.Printf("值:%v 类型:%T\n", str2, str2)
    //值:12.46 类型:string

	str3 := fmt.Sprintf("%t", t)
	fmt.Printf("值:%v 类型:%T\n", str3, str3)
    //值:true 类型:string

	str4 := fmt.Sprintf("%c", b)
	fmt.Printf("值:%v 类型:%T\n", str4, str4)
    //值:a 类型:string

strconv

FormatInt

参数1:int64 的数值

参数2:传值int类型的进制

	var i int = 20
	str1 := strconv.FormatInt(int64(i), 10)
	fmt.Printf("值:%v 类型:%T\n", str1, str1)
    //值:20 类型:string
	var f float32 = 20.231313
	str2 := strconv.FormatFloat(float64(f), 'f', 4, 32)
	fmt.Printf("值:%v 类型:%T\n", str2, str2

string类型转换成整型

	str := "123456"
    	/*
		ParseInt
		参数1:string数据
		参数2:进制
		参数3:位数 32 64 16

	*/
	num, _ := strconv.ParseInt(str, 10, 64)
	fmt.Printf("%v--%T", num, num)  //123456--int64
	/*
          ParseFloat
          参数1:string数据
          参数2:位数 32 64
 	*/
	str := "123456.333"
	// str := "123456.333xxxx"
	num, _ := strconv.ParseFloat(str, 64)
	fmt.Printf("%v--%T", num, num) //123456.333--float64

流程控制

if

基本写法

	age := 30
	if age > 18 {
		fmt.Println("成年人")
	} else {
		fmt.Println("不是成年人")
	}

特殊写法

	//当前区域内是全局变量
	age := 30 
	if age > 20 {
		fmt.Println("成年人", age)
	}
	fmt.Println(age)

	//局部变量
	if age2 := 34; age2 > 20 {
		fmt.Println("成年人", age2)
	}
	fmt.Println(age2) // undefined: age

for

基本写法

	for i := 1; i <= 5; i++ {
		fmt.Println(i)
	}

初始语句可以被忽略,但是初始语句后的分号必须要写

	i := 1
	for ; i <= 5; i++ {
		fmt.Println(i)
	}

初始语句和结束语句都可以省略

	i := 1
	for i <= 5 {
		fmt.Println(i)
		i++
	}

for range

类似js中的forEach

字符串

	var str = "你好golang"

	for k, v := range str {
		fmt.Printf("%v-%c,", k, v)
	}
    //0-你,3-好,6-g,7-o,8-l,9-a,10-n,11-g,

数组

	var arr = []string{"php", "java", "node", "golang"}
	for i := 0; i < len(arr); i++ {
		fmt.Printf("%v,", arr[i])
    }
    //php,java,node,golang
	
	for _, val := range arr {
		fmt.Printf(val)
	}
    //php,java,node,golang

switch case

基本使用

	var extname = ".css"
	switch extname {
	case ".html":
		fmt.Println("text/html")
		break
	case ".css":
		fmt.Println("text/css")
		break
	case ".js":
		fmt.Println("text/javascript")
		break
	default:
		fmt.Println("找不到此后缀")
	}

局部变量

	switch score := "D"; score {
	case "A", "B", "C":
		fmt.Println("及格")
	case "D":
		fmt.Println("不及格")
	}

一个分支可以有多个值,多个 case 值中间使用英文逗号分隔

	var n = 8
	switch n {
	case 1, 3, 5, 7, 9:
		fmt.Println("奇数")
		break //golang中break可以写也可以不写
	case 2, 4, 6, 8, 10:
		fmt.Println("偶数")
		break
	}

分支还可以使用表达式

	var age = 18
	switch {
	case age < 24:
		fmt.Println("好好学习")
	case age >= 24 && age <= 60:
		fmt.Println("好好赚钱")
	case age > 60:
		fmt.Println("注意身体")
	default:
		fmt.Println("输入错误")
	}

switch 的穿透 fallthrought

	var age = 30
	switch {
	case age < 24:
		fmt.Println("好好学习")
	case age >= 24 && age <= 60:
		fmt.Println("好好赚钱")
		fallthrough
	case age > 60:
		fmt.Println("注意身体")
	default:
		fmt.Println("输入错误")
	}
    
    //好好赚钱
    //注意身体

break

	for i := 1; i <= 10; i++ {
		if i == 2 {
			break
		}
		fmt.Println(i)
	}
	fmt.Println("继续执行")
    //1
    //继续执行

continue

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

goto

	var n = 30
	if n > 24 {
		fmt.Println("成年人")
		goto lable3

	}

	fmt.Println("aaa")
	fmt.Println("bbb")
lable3:
	fmt.Println("ccc")
	fmt.Println("ddd")
成年人
ccc
ddd

数组

数组的长度是类型的一部分

	var arr1 [3]int
	var arr2 [4]int
	var strArr [3]string

	fmt.Printf("arr1:%T  arr2:%T strArr:%T", arr1, arr2, strArr)
    //arr1:[3]int  arr2:[4]int strArr:[3]string

数组的初始化

第一种方法

	var arr1 [3]int

   arr1[0] = 23
   arr1[1] = 10
   arr1[2] = 24
   fmt.Println(arr1) //[23 10 24]
	// var strArr [3]string
   // strArr[0] = "php"
   // strArr[1] = "java"
   // strArr[2] = "golang"
   // // strArr[3] = "js" //out of bounds for 3-element array
   // fmt.Println(strArr) //[php java golang]

第二种方法

	var arr1 = [3]int{23, 34, 5}
   fmt.Println(arr1) //[23 34 5]

   var arr2 = [3]string{"php", "nodejs", "golnag"}
   fmt.Println(arr2) //[php nodejs golnag]

   arr3 := [3]string{"php", "nodejs", "golnag"}
   fmt.Println(arr3) //[php nodejs golnag]

第三种方法

一般情况下我们可以让编译器 根据初始值的个数自行推断数组的长度

	var arr1 = [...]int{12, 2324, 32435, 353, 535, 3535}

   fmt.Println(arr1) //[12 2324 32435 353 535 3535]

   fmt.Println(len(arr1)) //len()打印数组的长度 6

第四种方法

用指定索引值的方式来初始化数组

   arr := [...]int{0: 1, 1: 10, 2: 20, 5: 50}

   fmt.Println(len(arr)) //6

   fmt.Println(arr) //[1 10 20 0 0 50]

改变数组里面的值

	arr1 := [...]string{"php", "nodejs", "golnag", "js"}
   arr1[0] = "phper"
   fmt.Println(arr1)

数组的循环遍历

	var arr = [3]int{23, 34, 5}
	for i := 0; i < len(arr); i++ {
		fmt.Println(arr[i])
	}
	arr2 := [...]string{"php", "nodejs", "golnag", "js"}

	for k, v := range arr2 {
		fmt.Printf("key:%v value:%v\n", k, v)
	}

数组是值类型

值类型 :改变变量副本值的时候,不会改变变量本身的值 引用类型:改变变量副本值的时候,会改变变量本身的值

	var arr1 = [...]int{1, 2, 3}
	arr2 := arr1
	arr1[0] = 11
	fmt.Println(arr1)
	fmt.Println(arr2)

二维数组

	var arr = [3]int{1, 2, 3} //一维数组
	fmt.Println(arr)
	//二维数组
	var arr = [3][2]string{
		{"北京", "上海"},
		{"广州", "深圳"},
		{"成都", "重庆"},
	}
	fmt.Println(arr[0]) //[北京 上海]
	fmt.Println(arr[0][1]) //上海

不限定个数的二维数组
	var arr = [...][2]string{
		{"北京", "上海"},
		{"广州", "深圳"},
		{"成都", "重庆"},
		{"成都", "重庆"},
		{"成都", "重庆"},
	}

	fmt.Println(arr)

遍历二维数组

	var arr = [3][2]string{
		{"北京", "上海"},
		{"广州", "深圳"},
		{"成都", "重庆"},
	}
    	for _, v1 := range arr {
		for _, v2 := range v1 {
			fmt.Println(v2)
		}
	}
//北京
上海
广州
深圳
成都
重庆

切片

切片的声明 初始化

与数组相比不写长度

	var arr1 []int
	fmt.Printf("%v - %T - 长度:%v\n", arr1, arr1, len(arr1))
	//[] - []int - 长度:0
	var arr2 = []int{1, 2, 34, 45}
	fmt.Printf("%v - %T - 长度:%v\n", arr2, arr2, len(arr2))
    //[1 2 34 45] - []int - 长度:4

	var arr3 = []int{1: 2, 2: 4, 5: 6}
	fmt.Printf("%v - %T - 长度:%v", arr3, arr3, len(arr3))
    //[0 2 4 0 0 6] - []int - 长度:6

切片的默认值就是nil

	var arr1 []int
	var arr2 = []int{1, 2, 34, 45}
	fmt.Println(arr1) //[]
	fmt.Println(arr1 == nil) //true golnag中申明切片以后 切片的默认值就是nil
	fmt.Println(arr2 == nil) //false

切片的循环遍历

	var strSlice = []string{"php", "java", "nodejs", "golang"}
	for i := 0; i < len(strSlice); i++ {
		fmt.Println(strSlice[i])
	}
//php
java
nodejs
golang
	var strSlice = []string{"php", "java", "nodejs", "golang"}
	for k, v := range strSlice {
		fmt.Println(k, v)
	}
//0 php
1 java
2 nodejs
3 golang

基于数组定义切片

	a := [5]int{55, 56, 57, 58, 59} //数组
	b := a[:]                       //获取数组里面的所有值
	fmt.Printf("%v-%T\n", b, b)    
    //[55 56 57 58 59]-[]int
	a := [5]int{55, 56, 57, 58, 59} //数组
    c := a[1:4]
	fmt.Printf("%v-%T\n", c, c) //[56 57 58]-[]int
	a := [5]int{55, 56, 57, 58, 59} //数组
    d := a[2:]
	fmt.Printf("%v-%T\n", d, d) //[57, 58, 59]
	a := [5]int{55, 56, 57, 58, 59} //数组
    e := a[:3]                  //表示获取第三个下标前面的数据
	fmt.Printf("%v-%T\n", e, e) //[55, 56, 57]

基于切片定义切片

	a := []string{"北京", "上海", "广州", "深圳", "成都", "重庆"}
	b := a[1:]
	fmt.Printf("%v-%T\n", b, b) //[上海 广州 深圳 成都 重庆]

切片的长度和容量

长度:切片的长度就是它所包含的元素个数 容量:切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数

	s := []int{2, 3, 5, 7, 11, 13}
	fmt.Printf("长度%d 容量%d\n", len(s), cap(s)) //长度6 容量6
	s := []int{2, 3, 5, 7, 11, 13}
	a := s[2:]   //5, 7, 11, 13
	fmt.Printf("长度%d 容量%d\n", len(a), cap(a)) //长度4 容量4
	s := []int{2, 3, 5, 7, 11, 13}
    	b := s[1:3]                               //3, 5
	fmt.Printf("长度%d 容量%d\n", len(b), cap(b)) //长度2 容量5
s := []int{2, 3, 5, 7, 11, 13}
c := s[:3]                                //2, 3, 5
fmt.Printf("长度%d 容量%d\n", len(c), cap(c)) //长度3 容量6

make()函数创建一个切片

make([]T, size, cap)

	var sliceA = make([]int, 4, 8)
	fmt.Println(sliceA) //[0 0 0 0]
	fmt.Printf("%d--%d", len(sliceA), cap(sliceA)) //4--8

edit编辑切片

	var sliceA = make([]int, 4, 8)
	fmt.Println(sliceA) //[0 0 0 0]
	sliceA[0] = 10
	sliceA[1] = 12
	sliceA[2] = 40
	sliceA[3] = 30

	fmt.Println(sliceA) //[10 12 40 30]
	sliceB := []string{"php", "java", "go"}
	sliceB[2] = "golang"
	fmt.Println(sliceB) //[php java golang]
	var sliceC []int
	fmt.Printf("%v -- %v--%v", sliceC, len(sliceC), cap(sliceC)) //[] -- 0--0
	sliceC[0] = 1 //报错
	fmt.Println(sliceC)

append 切片动态添加元素

	var sliceA []int
	sliceA = append(sliceA, 12)
	sliceA = append(sliceA, 24)
	fmt.Printf("%v - %v--%v", sliceA, len(sliceA), cap(sliceA)) //[12 24] - 2--2
	var sliceA []int
	sliceA = append(sliceA, 12, 23, 35, 465)
	fmt.Printf("%v - %v--%v", sliceA, len(sliceA), cap(sliceA)) //[12 23 35 465] - 4--4

append 合并切片

	sliceA := []string{"php", "java"}
	sliceB := []string{"nodejs", "go"}
	sliceA = append(sliceA, sliceB...)
	fmt.Println(sliceA) //[php java nodejs go]

copy

切片就是引用数据类型

	sliceA := []int{1, 2, 3, 45}
	sliceB := sliceA
	sliceB[0] = 11
	fmt.Println(sliceA) //[11 2 3 45]
	fmt.Println(sliceB) //[11 2 3 45]
	sliceA := []int{1, 2, 3, 45}
	sliceB := make([]int, 4, 4)
	copy(sliceB, sliceA) 
	fmt.Println(sliceA) //[1 2 3 45]
	fmt.Println(sliceB) //[1 2 3 45]
	sliceB[0] = 111
	fmt.Println(sliceA) //[1 2 3 45]
	fmt.Println(sliceB) //[111 2 3 45]

delete

删除32

	a := []int{30, 31, 32, 33, 34, 35, 36, 37}
	a = append(a[:2], a[3:]...)
	fmt.Println(a)

删除35, 36

	sliceB := []int{30, 31, 32, 33, 34, 35, 36, 37}
	sliceB = append(sliceB[:5], sliceB[7:]...)
	fmt.Println(sliceB)

切片是引用类型

	s1 := make([]int, 3) //[0 0 0]
	s2 := s1             //将 s1 直接赋值给 s2,s1 和 s2
	s2[0] = 100
	fmt.Println(s1) //[100 0 0]
	fmt.Println(s2) //[100 0 0]

指针

变量的内存地址

	var a int = 10
	fmt.Printf("a的值:%v a的类型%T a的地址%p", a, a, &a) //a的值:10 a的类型int a的地址0xc0000100a8

指针变量

每一个变量都有自己的内存地址

	var a = 10
	var p = &a //p指针变量   p的类型 *int(指针类型)
	fmt.Printf("a的值:%v a的类型%T a的地址%p\n", a, a, &a)
    //a的值:10 a的类型int a的地址0xc000014090
	fmt.Printf("p的值:%v p的类型%T p的地址%p", p, p, &p)
    //p的值:0xc000014090 p的类型*int p的地址0xc000006028

指针获取变量

	a := 10
	p := &a         //p指针变量  类型 *int
	fmt.Println(p)  //a的地址  0xc0000100a8
	fmt.Println(*p) //*p 表示打印a对应的值   10

	*p = 30        //改变p这个变量对应的内存地址的值
	fmt.Println(a) //30

函数传指针参,改变变量的值

func fn1(x int) {
	x = 10
}

func fn2(x *int) {
	*x = 40
}

func main() {
	var a = 5
	fn1(a)
	fmt.Println(a) //5
	fn2(&a)
	fmt.Println(a) //40
}

make分配内存

map

	var userinfo map[string]string
	userinfo["username"] = "张三"
	fmt.Println(userinfo) //报错
	var userinfo = make(map[string]string)
	userinfo["username"] = "张三"
	fmt.Println(userinfo)

切片

	var a []int
	a[0] = 1
	fmt.Println(a) //报错
	var a = make([]int, 4, 4)
	a[0] = 1
	fmt.Println(a)

指针也是引用数据类型

map

定义

	var userinfo = make(map[string]string)
	userinfo["username"] = "张三"
	userinfo["age"] = "20"
	userinfo["sex"] = "男"
	fmt.Println(userinfo)
	fmt.Println(userinfo["username"])
	var userinfo = map[string]string{
		"username": "张三",
		"age":      "20",
		"sex":      "男",
	}
	fmt.Println(userinfo)
	userinfo := map[string]string{
		"username": "张三",
		"age":      "20",
		"sex":      "男",
	}
	fmt.Println(userinfo)

遍历

	userinfo := map[string]string{
		"username": "张三",
		"age":      "20",
		"sex":      "男",
	}
	for k, v := range userinfo {
		fmt.Printf("key:%v value:%v\n", k, v)
	}
//key:username value:张三
key:age value:20
key:sex value:男

修改

	var userinfo = map[string]string{
		"username": "张三",
		"age":      "20",
	}
	userinfo["username"] = "李四"
	fmt.Println(userinfo)

获取 查找

	var userinfo = map[string]string{
		"username": "张三",
		"age":      "20",
	}
	fmt.Println(userinfo["username"]) //获取
	v, ok := userinfo["age"]
	fmt.Println(v, ok) //20 true
	v, ok := userinfo["xxxxx"]
	fmt.Println(v, ok) // 空 和 false

删除

	var userinfo = map[string]string{
		"username": "张三",
		"age":      "20",
		"sex":      "男",
		"height":   "180cm",
	}
	fmt.Println(userinfo) //map[age:20 height:180cm sex:男 username:张三]

	delete(userinfo, "sex")
	fmt.Println(userinfo) //map[age:20 height:180cm username:张三]

map类型的切片

	var userinfo = make(map[string][]string)

	userinfo["hobby"] = []string{
		"吃饭",
		"睡觉",
		"敲代码",
	}

	userinfo["work"] = []string{
		"php",
		"golang",
		"前端",
	}

	for _, v := range userinfo {
		// fmt.Println(k, v)
		for _, value := range v {
			fmt.Println(value)
		}
	}
吃饭
睡觉
敲代码
php
golang
前端

map是引用类型

	var userinfo1 = make(map[string]string)
	userinfo1["username"] = "张三"
	userinfo1["age"] = "20"
	userinfo2 := userinfo1
	userinfo2["username"] = "李四"
	fmt.Println(userinfo1)
	fmt.Println(userinfo2)

map升序

	map1 := make(map[int]int, 10)
	map1[10] = 100
	map1[1] = 13
	map1[4] = 56
	map1[8] = 90
	map1[11] = 100
	map1[2] = 13
	var keySlice []int
	for key, _ := range map1 {
		keySlice = append(keySlice, key)
	}
	fmt.Println(keySlice) //[11 10 4 8 2 1]
	// // 让key进行升序排序
	sort.Ints(keySlice)
	fmt.Println(keySlice) //[1 2 4 8 10 11]

map统计字符次数

	var str = "how do you do"
	var strSlice = strings.Split(str, " ")
	fmt.Println(strSlice)

	var strMap = make(map[string]int)
	for _, v := range strSlice {
		strMap[v]++
	}
	fmt.Println(strMap) //map[do:2 how:1 you:1]