Go语言学习之路(九)复合数据类型

时间:2024-03-22 10:46:14

一、数组

1.数组定义
一:var a [10]int=[10]int{1,2,3,4,5,6}
二:
var arr[10] int
fori,_:=rangearr{
fmt.Scan(&arr[i])
}

2.数组的自动推导类型

names := [5]int{1,2,3,4,5}

for_,data:=range names{
fmt.Println(data)
}
3.

2.数组作为函数参数

func main(){

//var a [5]int=[5]int{10,20,30,40,50}
a:=[...]int{10,20,30,40,50}
Modify(a)
fmt.Println(a[0])
}

func Modify(a [5]int){
a[0]=666
}

数组作为函数参数时必须给定数组个数,否则会因为数组越界运行时错误
数组作为函数参数时是按值传递的

3.数组作为函数返回值
import(
"math/rand"
"time"
"fmt"
)

func main(){

arry:=Teat()
fmt.Println(arry)
}

func Teat()[3]int{
vararr[3]int

rand.Seed(time.Now().Unix())
for i:=0;i<3;i++{
arr[i]=rand.Intn(100)
}

return arr
}


同数组作为参数一样,数组作为返回值时,需要给定数组界限
 

二、二维数组

func main(){
var nArry[3][4]int

//fmt.Println(len(nArry[0]))
for i:=0;i<len(nArry);i++{
for j:=0;j<len(nArry[i]);j++{
fmt.Scan(&nArry[i][j])
}
}

fmt.Println(nArry)
}

结果:
1 2 3 4 5 6 7 8 9 10 11 12
[[1 2 3 4] [5 6 7 8] [9 10 11 12]]

nArry为外层数组其中的数据类型为一个一维数组
nArry[0]即二维数组中的一个元素,即一个一维数组
 

三、切片

不是指向数组的指针,是一种新定义的数据结构。 包含 指向数组地址的成员、长度、容量。    runtime/slice.go    

        type slice struct {
            *Pointer    
            len
            cap
        }


切片定义方式:
    第一种:
        nSlice:=[]int{1,2,3,4,5}
        nSlice=append(nSlice,6,7,8)
        
        fmt.Println(nSlice)
    第二种:
        var s1 []float64
        s1=[]float64{1,2.3}
        fmt.Println(s1)
    第三种:采用make函数(make(类型,长度,容量))
        s2:=make([]int,5,10)
        fori:=0;i<len(s2);i++{
        s2[i]=i
        }
        fmt.Println(s2)
        
        fmt.Println(len(nSlice))
        fmt.Println(cap(nSlice))

        
容量一般是从slice的开始位置到底层数据的结尾位置,容量是固定的

关于切片的一些理解:
    数组是拥有固定长度的,对于切片来说类似于一个可变长数组。
    想象一下插入750000条数据到数组中去,而这个数组的长度从10开始,需要进行18次的分配,最后结束的数组长度为560720 。所以最好给数组选择一个合适的大小,但是事实上你只能对大小有一个粗略的估计,所以最好选择比预期大小稍大一点的空间,而大小则为切片的实际大小。
    
    由于append算法的帮助我们可以完成动态数组。
    关于append算法:
        if 数组长度 == 数组容量{
            //开辟一个数组容量为原来两倍的新数组
            make([]int,原始数组长度+1,数组容量*2)
            //把原始数组中的值全部拷贝到新的数组中去
        }
        
        //把新值插入到数组中去
        
        //返回新数组
        
    举例说明:
    x:=[]int{1,2,3,4}
    fmt.Println(len(x))//原始数组长度
    fmt.Println(cap(x))//原始数组容量
    
    x=append(x,5)
    fmt.Println(len(x))//新数组长度
    fmt.Println(cap(x))//新数组容量
    
    结果:
    4
    4
    5
    8
    
    关于append算法的具体实现:
    unc insert(original []int, position int, value int) []int {   l := len(original)   target := original   if cap(original) == l {     target = make([]int, l+1, l+10)     copy(target, original[:position])   } else {     target = append(target, -1)   }   copy(target[position+1:], original[position:])   target[position] = value   return target }
    
    来自 <https://www.openmymind.net/Controlling-Array-Growth-In-Golang/> 
    
    如果容量超过1024字节则,扩大为上一容量的1.25倍

切片的截取:
    和大部分切片的原理类似都是左闭右开


切片作为函数参数:
    func GetRandom(nArry[]int){
    var num int
    
    FLAG:
    rand.Seed(time.Now().UnixNano())
    
    for{
    num=rand.Intn(10000)
    
    if 999<num&&10000>num{
    nArry[0]=num/1000
    nArry[1]=num/100%10
    nArry[2]=num/10%10
    nArry[3]=num%10
    
    for i:=0;i<len(nArry)-1;i++{
    for j:=i;j<len(nArry)-1;j++{
    if nArry[i]==nArry[j+1]{
    goto FLAG
    }
    }
    }
    
    break
    }
    
    }
    }
    

字符串可以和字符类型相互转换
    func main(){
        //字符切片和字符串类型 可以进行转换
    
        ////字符串
        //var str string="hello"
        ////字符切片
        var ch []byte
        ////类型转换
        //ch=[]byte(str)
    
        //var ch[]byte=[]byte{'h','e','l','l','o'}
        ch=[]byte("hello")
    
        //for i:=0;i<len(ch) ;i++  {
        //    fmt.Printf("%s",ch[i])
        //}
    
        fmt.Printf("%s",ch)
    }

 

四、字符串

(一)字符串处理函数

1.func Contains(s string, substr string)bool

检测字符串是否包含substr,返回bool值

2.func Join(a[] string, sep string)string

通过sep把字符串连接起来

3.func Index(s string, sep string)int

在字符串s中查找sep所在的位置,找不到返回-1

4.func Repeat(s string, count int)string

重复s字符串count次,最后返回重复的数字

5.func Replace(s string,old string, new string, n int)string

在s字符串中,把old字符串替换为new字符串,n表示替换的次数,小于0表示全部替换

6.func Split(s string, sep string)[]string

把s字符串按照sep分割,返回slice

7.func Trim(s string,cutset string)string

在s字符串中的头部和尾部取出cutset指定的字符串

8.func Fields(s string)[]string

去除s字符串得空格符,并且按照空格分割返回slice

(二)字符串转换

1.Format数据类型 其它数据转化为字符串

2.Parse数据类型 字符串转化为其它数据

3.append数据类型 将其它类型转化为字符串

 

五、map散列表

1.map的定义
    map[键数据类型]数值数据类型
(1)map的第一种定义方式

Go语言学习之路(九)复合数据类型

Go语言学习之路(九)复合数据类型

(2)利用make

Go语言学习之路(九)复合数据类型

Go语言学习之路(九)复合数据类型

因为byte类型时根据ASCII码形式存储的,所以打印出的键值为各字符所对应的ASCII码值
2.map是一种链式结构,并不按照顺序存储

Go语言学习之路(九)复合数据类型

3.map作为函数参数时是按址传递
4.map添加值,map的长度是自动增加的
5.map当中的键值是唯一的
6.可以通过delete(map,key)删除元素
7.map当中的值为可以为符合数据类型
例如:var m map[string][] int


六、结构体

1.结构体定义
type 结构体名 struct{
}

Go语言学习之路(九)复合数据类型

Go语言学习之路(九)复合数据类型

通过.的操作符可以访问到结构体中的数据

Go语言学习之路(九)复合数据类型

Go语言学习之路(九)复合数据类型

2.结构体数组

Go语言学习之路(九)复合数据类型

Go语言学习之路(九)复合数据类型

  结构体切片

Go语言学习之路(九)复合数据类型

Go语言学习之路(九)复合数据类型

3.结构体作为函数参数

Go语言学习之路(九)复合数据类型

Go语言学习之路(九)复合数据类型

4.结构体作为函数参数其传递方式按照所定义的类型决定,比如结构体变量结构体数组为按值传递,     结构体切片以及结构体字典为按址传递
 

七、指针

指针    啥是指针
        指针就是用来指向变量地址的变量
    指针的定义
        var a int  var p *int = &a
        var p *int  p是一个空指针,不能赋值,不能调用。指针的默认值为nil,地址为0x0
        野指针指向一段垃圾内存的指针,var p *int = 0xfff00,不能被使用
    指针作为函数参数
        按址传递
    数组指针
        指向数组的指针
            var p *[10]int
        解引用指针值为数组的地址,可以通过指针下标p[下标]直接访问数组内容
    指针数组
        其值为指针的数组
            var p [20]*int
    切片指针
        指向切片的指针
            var p *[]int
        解引用指针值为切片地址,不能直接通过指针下标p[下标]访问切片内容,需要通过(*p)[下标]访问切片内容。
        在使用append的时候,如果切片容量不够,开辟出新的内存空间,可能造成实参和形参指向的内存地址不同,栈消亡,形参不能改变实参
    指针切片
        其值为指针的切片
            var p []*int
    结构体指针
        指向结构体的指针
            var p *student
    new
        int *p = new(int)
        int *p = new([10]int)
        int *p = new([]int)
        int *p = new(student)
啥是指针
    指针就是用来指向变量地址的变量
指针的定义
    var a int  var p *int = &a
    var p *int  p是一个空指针,不能赋值,不能调用。指针的默认值为nil,地址为0x0
    野指针指向一段垃圾内存的指针,var p *int = 0xfff00,不能被使用
指针作为函数参数
    按址传递
数组指针
    指向数组的指针
        var p *[10]int
    解引用指针值为数组的地址,可以通过指针下标p[下标]直接访问数组内容
指针数组
    其值为指针的数组
        var p [20]*int
切片指针
    指向切片的指针
        var p *[]int
    解引用指针值为切片地址,不能直接通过指针下标p[下标]访问切片内容,需要通过(*p)[下标]访问切片内容。
    在使用append的时候,如果切片容量不够,开辟出新的内存空间,可能造成实参和形参指向的内存地址不同,栈消亡,形参不能改变实参
指针切片
    其值为指针的切片
        var p []*int
结构体指针
    指向结构体的指针
        var p *student
new
    int *p = new(int)
    int *p = new([10]int)
    int *p = new([]int)
    int *p = new(student)