• 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
    ",key ,value)
    }
    

    遍历获得字符

    	str := "hello"
    	for key, value := range str {
    		fmt.Printf("key%d, value 0x%x 
    ",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)
    }()
    
    for value :=range c {
    		...
    }
    

    编译

    export GOPATH=/home/golang/code
    go build -o main /goinstall                 # 按包编译
    
    go build -o mian main.go lib.go             # 文件列表编译
    
    

    go run

    命令会编译源码,并且直接执行源码的main()函数,不会在当前目录留下可执行文件。

    go run不会在运行目录下生成任何文件,可执行文件被放在临时文件中被执行,工作目录被设置为当前目录。
    在go run的后部可以添加参数,这部分参数会作为代码可以接受的命令行输入提供给程序。
    go run不能使用“go run + 包”的方式进行编译,如需快速编译运行包,需要使用如下步骤来代替:

    • 使用go build生成可执行文件。
    • 运行可执行文件。

    go install

    功能和go build类似,附加参数绝大多数都可以与go build通用。go install只是将编译的中间文件放在GOPATH的pkg目录下,以及固定地将编译结果放在GOPATH的bin目录下。

    go install的编译过程有如下规律:

    • go install是建立在GOPATH上的,无法在独立的目录里使用go install。
    • GOPATH下的bin目录放置的是使用go install生成的可执行文件,可执行文件的名称来自于编译时的包名。
    • go install输出目录始终为GOPATH下的bin目录,无法使用-o附加参数进行自定义。
    • GOPATH下的pkg目录放置的是编译期间的中间文件。

    测试

    go test指定文件时默认执行文件内的所有测试用例。可以使用-run参数选择需要的测试用例单独执行

    -v,可以让测试时显示详细的流程

    -run跟随的测试用例的名称支持正则表达式,使用-run Test A$即可只执行Test A测试用例(假设TestA、TestAk、TestB、TestC会执行TestA、TestAk)。

    go test -v -run testA main_test.go
    
  • 相关阅读:
    关于Lua中的面向对象实现
    当我读《体验引擎:游戏设计全景探秘》时我在想什么
    【Unity】拖动图片生成对应Image
    【Unity】阅读LuaFramework_UGUI的一种方法
    【Unity】关于VS条件编译符号
    Lua元表应用举例:配置表格转为Lua配置表
    对文件夹下的git项目进行批量更新、打包
    二分查找
    python-变量及字符串赋值|今日所学-2017-12-26
    lamda- filter,map, collect
  • 原文地址:https://www.cnblogs.com/followyou/p/12733509.html
Copyright © 2020-2023  润新知