设为首页 加入收藏

TOP

Go语言备忘录:基本数据结构(一)
2017-09-30 13:21:03 】 浏览:1327
Tags:语言 备忘录 基本 数据结构

本文内容是本人对Go语言的变量、常量、数组、切片、映射、结构体的备忘录,记录了关键的相关知识点,以供翻查。

文中如有错误的地方请大家指出,以免误导!转摘本文也请注明出处:Go语言备忘录:基本数据结构多谢!

 参考书籍《Go语言圣经》、《Go语言实战》、《Go语言学习笔记》等

一、变量

  •  变量是一段或多段用来存储数据的内存;
  • 变量总是有固定的数据类型,类型决定了所占内存的长度和存储格式;
  • 编译后的代码使用变量的内存地址来访问数据,而不是变量名;
  • 简短变量声明只能在函数内声明(局部变量),var声明方式则无限制(但一般用于声明未显式初始化的变量);
  • 声明同一作用域中的同名变量时,将回退为赋值,即重用该变量(必须至少有一个新变量定义);
  • 而声明不同作用域的同名变量则为重新定义(覆盖);
var q int
var y = 453
var (
    n,m = 134,"srf"
    n1,m1 int 
)
func f1() {
    n,m := 25,"sss" 
    n,m1 := 34,"yyy"
    fmt.Println(n,m,m1)
    n = n+5 //赋值表达式中,首先计算右值
    //“_”空标识符用来临时规避编译器对未使用变量和导入包的错误检查
    if _,ok := add1(n);ok {
        fmt.Println(n)
    }
}
func add1(n int) (int, bool) {
    return n+1,true
}

  

二、常量、枚举
  • 常量是一个不可改变的值,它可以为字面量,或编译器能计算出结果的表达式。未使用的常量不会引起编译错误;
  • 在常量组中如不指定类型和初始值,则与上一行非空常量右值相同;
  • 常量会被编译器在预处理阶段直接展开,作为指令数据使用,所以无法取常量的地址;
const i = 5
const (
    x byte = 1
    x1
    x2       //x1,x2均为1
    s = "abs"
    s1       //s1=“abc”
)
const (
    _,_ int = iota,iota*3 //0,0*3 忽略值,并显式指定类型为int
    k1,k2             //1,1*3
    l1,l2             //2,2*3
    o1,o2 = 5,6       //中断iota自增
    r1,r2             //5,6  同上一行
    e1,e2 = iota,iota*3 //5,5*3  恢复iota自增,按行递增
)
//枚举
type color byte
const (
    blue color = iota
    red
    green
)
func main() {
    t:= blue
    fmt.Println(t) //0
    //fmt.Println(&i) //错误:无法对常量取地址 cannot take the address of i
}

  

三、数组

  • 数组是切片和映射的基础数据结构。数组是值类型,在赋值和传递数组时将拷贝整个数组。
  • 数组是一个长度固定的数据类型,存储着一段具有相同数据类型元素的连续内存块。
  • 因为数组占用的内存是连续分配的,所以对数组元素的查询、修改等操作速度很快。
  • 声明数组的方式:
    • var array1 [5]int
    • array1 := [5]int{3,5,6,3,2}
    • array1 := [...]int{3,4,7,8,1} //根据数组字面量中元素的个数来确定数组的长度
    • array1 := [5]int{0:3,3:5,4:8} //只初始化指定索引的元素,其余元素保持零值
    • array1 := [...]int{1,2,9:32}
  • 数组元素的类型可以为任何内置类型,也可以是某种结构类型,也可以是指针类型。
  • 数组变量的类型包括数组长度和元素的类型,只有两部分都相同的数组才可相互赋值。
  • 多维数组:数组本身只有一个维度,只能通过组合多个数组来创建多维数组;内置函数len、cap均返回第一维度的长度
    • var array [4][2]int
    • array := [4][2]int{2:{20,21},3:{41,25}}
    • array := [4][2]int{2:{1:21},3:{0:41}}
    • array := [...][4]int{{2,3},{4,5}} //仅第一维度允许使用“...”
    • array[2][1] = 10
  • 在函数间传递数组:由于在函数间传递变量时,传递的总是变量的值的副本,因为数组是值类型,所以在赋值和传递数组变量时将拷贝整个数组!在定义函数时,对于较大的数据类型应该把参数设计为指针类型,这样在调用函数时,只需在栈上分配给每个指针8字节的内存,但这意味着会改变指针指向的值(共享的内存),其实大部分情况下应该使用切片类型,而不是数组。
  • 注意:因为切片的底层数组可能会在堆上分配内存,对于小数组在栈上拷贝的消耗可能比make代价小;
四、切片slice
  • 切片slice是引用类型,它内部通过指针引用一个底层数组,并设定相关属性将数据的读写操作限定在指定区域。
//切片本身是个只读对象,工作机制类似数组指针的一种包装
type slice struct{
    array unsafe.Pointer
    len int //可读写的元素数量
    cap int //所引用数组片段的真实长度
}
  • 创建和初始化:
    • slice1 := make( []string, 5 ) //创建一个长度、容量都为5的string类型的切片
    • slice1 := make( []string, 3, 5 ) //创建一个长度为3,容量为5的string类型的切片
    • slice2 := []string{ "red","blue","green" } //长度和容量均为3的切片
    • slice2 := []int{ 99:1 } //长度和容量均为100,并初始化第100个元素为1
  • 再次切片reslice:以开始和结束原切片的索引位置确定所引用的数组片段,不支持反向索引,实际范围是一个右半开区间
    假设原切片slice容量为k,新切片newSlice为原切片的索引 i 元素位置开始,在原切片的容量范围内取值
    • newSlice := slice[ i : j ]  //长度为j-i,容量为k-i
    • newSlice := slice[ i : j : n ] //限制新切片的容量为n-i(第三个参数n-1表示新切片可扩展到的最后一个可见的底层数组部分的元素索引,这样就达到了限制容量的目的,注意:n必须>=j)
    • 新切片无法访问它所指向的底层数组的第一个元素之前的部分(第一个索引之前的部分)
    • 例子:ss:=[]int{10,20,30,40,50}       newss:=ss[2:4:5]   //newss为[30,40],容量为3
    • 新切片和旧切片指向同一个底层数组;
//利用reslice实现一个栈式结构(也可将stack定义为一个类型)
var stack = make([]int,0,5)

func push(x int) error {
	n:=len(stack)
	if n == cap(stack) {
		return errors.New("st
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇推荐一款接口文档在线管理系统-Mi.. 下一篇gogland跨平台编译

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目