Go知识记录

简介

目前正在学Go,做下记录,温故而知新,初学coding的时候可以快速翻查用法,了解原理。

多重赋值

多重赋值时,变量的左值和右值按从左到右的顺序赋值

var a int = 100
b := 200
b,a = a,b       // 实现交换

匿名变量

匿名变量 '_'表示,使用匿名变量时,只需要在变量声明的地方使用下划线替换即可。

a,_ = Get_data()

匿名变量不占用空间,不会分配内存。匿名变量与匿名变量之间不会因为多次声明而无法使用。

数据类型

整形(int8,int16,int32,int64)、浮点型、布尔型、字符串、数组、切片、结构体、函数(go语言的一种数据类型,可对函数类型的变量进行赋值和获取)、map、通道(channel)

数组

var variable_name [SIZE] variable_type

数组是一串固定长度的连续内存区域。

数组可以在声明时使用初始化列表进行元素设置:

var team = [3]string{"hammer","soldier","mum"}

根据元素个数确定数组大小

var team = [...]string{"hammer","soldier","mum"}   // ...表示让编译器确定数组大小

遍历数组

for k,v := range team{
    fmt.Println(k,v)
}

切片

https://www.cnblogs.com/followyou/p/12349883.html

map

https://www.cnblogs.com/followyou/p/12355313.html

函数

https://www.cnblogs.com/followyou/p/12348259.html

结构体

https://www.cnblogs.com/followyou/p/12358919.html

接口(interface)

https://www.cnblogs.com/followyou/p/12601846.html

指针

go拆分两个核心概念

  • 类型指针 允许对这个指针类型的数据进行修改。传递数据使用指针,而无需拷贝数据。类型指针不能进行偏移和运算
  • 切片 由指向起始元素的原始指针、元素数量和容量组成

go的指针类型变量拥有指针的高效访问,但又不会发生指针偏移,从而避免非法修改关键性数据问题。同时,垃圾回收也比较容易对不会发生偏移的指针进行检索和回收。

切片比原始指针具备更强大的特性,更为安全。切片发生越界时,运行时会报出宕机,并打出堆栈,而原始指针只会崩溃。

指针地址和指针类型

ptr := &v //v的类型为T  &v取地址 &取地址操作符

//v代表被取地址的变量,被取地址的v使用ptr变量进行接收,ptr的类型为*T,称作T的指针类型。
// * 代表指针

变量、指针和地址关系:每个变量都拥有地址,指针的值就是地址

从指针获取指针指向的值

& 获取这个变量的指针

  • 指针取值

&取出地址,*根据地址取出地址指向的值

变量、指针地址、指针变量、取地址、取值关系:

  • 对变量进行取地址(&)操作,可以获得这个变量的指针变量
  • 指针变量的值是指针地址
  • 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值

*操作符根本意义就是操作指针指向的变量。当操作在右值时,就是取指向变量的值;当操作在左值时,就是将值设置给指向的变量

类型转换

T(表达式)

T代表要转换的类型。、

var a int32 = 1047483647
b:=int16(a)

堆栈知识

  • 栈区(stack) --存储参数值、局部变量,维护函数调用关系等。
  • 堆区(heap) --动态内存区域,随时申请和释放,程序自身要对内存泄漏负责
  • 全局区(静态区) --存储全局和静态变量
  • 字面量区 --常量字符串存储区
  • 程序代码区 --存储二进制代码
int a=o;    //全局变量
char *p1;   //全局未初始化区
main() {
    static int b=0;   //全局初始化区
    int c;  //栈
    char d[] = "abc:;  //栈
    char *p2;          //栈
    char *p3 = "hello";   //hello在常量区,p3在栈上
    p1 = (char*)malloc(10);
    p2 = (char*)malloc(20);     //分配得来的10和20字节的区域就在堆区
    strcpy(p1,"hello");        //hello放在常量区,编译器可能会将它与p3所指向的hello优化成一个地方
}

总体来讲,栈上的变量是局部的,随着局部空间的销毁而销毁,由系统负责。

堆上的变量可以提供全局访问,需要自行处理其声明周期。

关键字

defer

defer用于资源的释放,会在函数返回之前进行调用

var a,b := 1,2
c := func(a,b int) (c int){
		c  = a+b
		defer func() {
			c = c*2
		}()
		return
	}
//6

流程判断

  • 条件判断 if
  • 条件循环 for
  • 健值循环 for range
  • 分支选择 switch
    switch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case,如果我们需要执行后面的 case,可以使用 fallthrough
switch var1 {
    case val1:
        fallthrough
    case val2:
        ...
    default:
        ...
}
  • 跳转 goto
  • 跳出循环 break 和 继续循环 continue

健值循环(for range)

可以使用for range遍历数组、切片、字符串、map、及chnnel。

通过for range遍历返回值规律:

  • 数组、切片和字符串返回索引和值;
  • map返回健和值
  • chnnel只返回通道内的值

遍历切片、数组

for key, value := range []int{1, 2, 3, 4} {
		fmt.Printf("key%d, value %d\n",key ,value)
}

遍历获得字符

	str := "hello"
	for key, value := range str {
		fmt.Printf("key%d, value 0x%x \n",key ,value)  //%x	十六进制,小写字母,每字节两个字符
	}

遍历map

	m := map[string]int{
		"a" : 1,
		"b" : 2,
	}
	for key, value := range m {
		fmt.Println(key,value)
	}

遍历channel --从通道接收数据

c := make(chan int)
go func(){
		//往通道内推送数据,然后结束并关闭通道
		c <- 1
		c <- 2
		c <- 3
		close(c)
}()

猜你喜欢

转载自www.cnblogs.com/followyou/p/12733509.html