Golang学习笔记

〇、Go可以做什么?

学习方向

区块链研发工程师、Go服务器端/游戏软件开发工程师、Go分布式/云计算软件工程师

一、基础知识

1.1 Go程序开发注意事项(⭐⭐⭐)

  1. Go源代码以“go”为扩展名;
  2. Go应用程序的执行入口是main()方法;
  3. Go语言严格区分大小写;
  4. Go方法由一条条语句构成,每个语句不需要分号(Go语言会在每行后自动加分号),这体现出Go语言的简洁性;
  5. Go编译器是一行行进行表一的,因此我们一行就写一条语句,不能多条语句写在同一行,否则会报错;
  6. Go语言定义的变量或者import包如果没有使用到,代码不能编译通过(只要声明的东西或引用的包就一定要用到);
  7. 大括号成对出现,缺一不可。

1.2 注释(comment)

Go支持C语言风格的/* */块注释,也支持C++风格的//行注释。行注释更通用,块注释主要用于针对包的详细说明或者屏蔽大块的代码。

Go官方推荐使用行注释来注释整个方法和语句。

  1. 行注释
  2. 块注释(多行注释)
func main() {
    // 行注释规范
    // fmt.Println("Hello,world")
    fmt.Println("Hello,world")
    /*
    块注释规范
    fmt.Println("Hello,world")
    fmt.Println("Hello,world")
    */
    fmt.Println("Hello,world")
}

1.3 变量

变量是程序的基本单位,变量相当于内存中的一个存储空间的表示,可以把变量当成一个房间的门牌号,通过门牌号我们可以找到房间,同理,通过变量可以访问到变量的值。

func main() {
    // 1.声明变量
    var name string
    // 2.给变量name赋值
    name = "武松"
    // 3.使用变量
    fmt.Println("姓名=", name)
}

1.3.1 变量使用注意事项(⭐⭐⭐)

  1. 变量标识内存中的一个存储区域;

  2. 该区域有自己的名称(变量名)和类型(数据类型);

  3. Golang变量使用的三种方式:

    第一种:指定变量类型,声明后如果不复制,使用默认值;

    var age int
    fmt.Println("age=", age)
    

    第二种:根据值自行判定变量类型;

    var age = 18
    fmt.Println("age =", age)
    

    第三种:省略var,注意::=左侧的变量不应该是已经声明过的(类型推导),否则导致编译错误;

    age := 18
    fmt.Println("age =", age)
    
  4. 多变量声明

    在编程中,有时我们需要一次性声明多个变量,Golang也提供这种语法。

func main() {
    // 指明类型
    var n1, n2, n3 int
    fmt.Println(n1, ",", n2, ",", n3)
    // 自行判定
    var n4, n5, n6 = 100, "tom", 11.1
    fmt.Println(n4, ",", n5, ",", n6)
    // 类型推导
    n7, n8, n9 := 100, "tom", 11.1
    fmt.Println(n7, ",", n8, ",", n9)
}

1.3.2 变量的数据类型

bit:计算机中最小的存储单位。

byte:计算机中基本存储单元。

Golang的字符串是由字节组成。

数据类型
类型有无符号占用存储空间表数范围备注
int81字节-128~127
int162字节-215~215-1
int324字节-231~231-1
int648字节-263~263-1
unint81字节0~255
uint162字节0~2^16-1
uint324字节0~2^32-1
uint648字节0~2^64-1
int32位系统4个字节;64位系统8字节-231~231-1;-263~263-1
uint32位系统4个字节;64位系统8字节02^32-1;02^64-1
rune与int32一样等价于int32,标识一个Unicode码
byte与uint8等价当要存储字符时选择byte
float324字节-3.403E38~3.403E38单精度
float648字节-1.798E308~1.798E308双精度
bool1字节布尔类型

字符串(string)类型

字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的,Go语言的字符串的字节使用UTF-8编码标识Unicode文本。

// golang中string类型使用
func main() {
    var name string = "张三"
    fmt.Println("name=", name)
}

字符串使用注意事项

  1. 字符串一旦赋值,字符串就不能修改;在Go中字符串是不可变的。
  2. 字符串拼接的时候加号要留在上面。

基本数据类型默认值

数据类型默认值
整型0
浮点型0
字符串“”
布尔类型false

1.3.3 基本数据类型的相互转化

Golang和Java/c不同,Go在不同类资那个的变量之间赋值时需要显示转换。也就是说Go中数据类型不能自动转换

基本语法

表达式T(v)将值v转换成类型T

T:就是数据类型,比如int32、int64、float32等

v:就是需要转换的变量

/* 
表达式T(v)将值v转换成类型T
T:就是数据类型,比如int32、int64、float32等
v:就是需要转换的变量
*/
func main() {
    var age int = 100
    var age2 = float32(age)
    fmt.Printf("age=%v,age2=%v\n", age, age2)
}

使用细节 (⭐⭐⭐)

  1. Go中,数据类型的转换可以是从表示范围小->表示范围大,也可以是范围大->范围小(需要注意取值范围);

    func main() {
        // 下面代码无法编译通过,需要进行类型转换。
        var n1 int32 = 12
        var n2 int64
        var n3 int8
    
        n2 = n1 + 20 // int32->int64 【编译报错,无法自动转换】
        n3 = n1 + 20 // int32->int8【编译报错,无法自动转换】
    }
    
  2. 被转换的是变量存储数据(值),变量本身的数据类型并没有变化;

  3. 在转换中,比如将int64转换成int8【-128~127】编译不会报错,只是转换的结果是按溢出处理,与期望结果不同。因此,在转换时需要考虑范围。

func main() {
    var age int32 = 999999

    var age2 int8 = int8(age)
    fmt.Println("age2=", age2)	// 编译不会报错,但是结果为【age2=63】,与预期结果不同
}

1.3.4 基本数据类型转string(⭐⭐⭐)

在程序开发过程中,我们经常需要将基本数据类型转换成string类型,或者将string类型转成基本数据类型。

→ 方式1

fmt.Sprintf(“%参数”,表达式) 【推荐使用,较为灵活】

函数介绍:

参数需要和表达式的数据类型相匹配,fmt.Sprintf()会返回转换后的字符串

func main() {
    var num1 int = 100
    var num2 float64 = 23.899
    var b bool = true
    var myChar byte = 'a'
    var str string // 空字符串

    // 使用第一种方式转换fmt.Printf()
    str = fmt.Sprintf("%d", num1)
    fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="100"】

    str = fmt.Sprintf("%f", num2)
    fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="23.899000"】

    str = fmt.Sprintf("%t", b)
    fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="true"】

    str = fmt.Sprintf("%c", myChar)
    fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="a"】
}
→ 方式2

使用strconv包的函数

func main() {
    
    var num3 int = 100
    var num4 float64 = 23.899
    var num5 int = 1234567
    var b2 bool = true
    // 使用第二种方式strconv函数
    str = strconv.FormatInt(int64(num3), 10)
    fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="100"】

    /*
       说明:
       'f'表示格式;
       10:表示小数位保留十位;
       64:表示这个小数是float64
    */
    str = strconv.FormatFloat(num4, 'f', 10, 64)
    fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="23.8990000000"】

    str = strconv.Itoa(num5)
	fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="1234567"】
    
    str = strconv.FormatBool(b2)
    fmt.Printf("str type is %T,str=%q\n", str, str) // 运行结果:【str type is string,str="true"】
}

1.3.5 string类型转基本数据类型

使用的是strconv包的函数

func main() {
    var str string = "true"
    var b bool

    /*
       strconv.ParseBool(str)说明:
       1.函数会返回两个值(value bool,err error)
       2.我只想获取value bool,不想获取err 所以使用"_"忽略
    */

    b, _ = strconv.ParseBool(str)
    fmt.Printf("b type is %T,b=%v\n", b, b) // 运行结果:【b type is bool,b=true】

    var str2 string = "123456"
    var n1 int64
    var n2 int
    /*
       说明:
       1.第一个参数表示对应的str字符串
       2.第二个参数表示几进制
       3.第三个参数表示int的精度
    */
    n1, _ = strconv.ParseInt(str2, 10, 64)
    fmt.Printf("n1 type is %T,n1=%v\n", n1, n1) // 运行结果:【n1 type is int64,n1=123456】

    // 类型转换
    n2 = int(n1)
    fmt.Printf("n2 type is %T,n2=%v\n", n2, n2) // 运行结果:【n2 type is int,n2=123456】
    
    var str3 string = "123.99999"
    var f1 float64
    f1, _ = strconv.ParseFloat(str3, 64)
    fmt.Printf("f1 type is %T,f1=%v\n", f1, f1) // 运行结果:【f1 type is float64,f1=123.99999】
}

其他说明:因为返回的都是int64或者float64,如果希望得到int32、float32需要进行类型转换处理

注意事项:

再将string类型转换成基本数据类型时,要确保string类型能够进行有效的转换,比如我们可以将“123”转成一个整数,但是不可以将“hello”转成一个整数,如果这样做,Go会直接将其转成0

var str4 string = "hello"
var n3 int64
n3, _ = strconv.ParseInt(str4, 10, 64)
fmt.Printf("n3 type is %T,n3=%v\n", n3, n3) // 运行结果:【n3 type is int64,n3=0】

1.4 指针

1.4.1基本介绍

  1. 基本数据类型,变量存的就是值,也叫值类型;
  2. 获取变量的地址,用&,比如:var num int,获取num的地址就是:#
  1. 指针类型,变量存的就是一个地址,这个地址指向的空间存的才是值,比如:var ptr *int=#

  2. 获取指针类型所指向的值,使用:*,比如:var ptr *int,使用 *ptr获取ptr指向的值;

func main() {
    // 基本数据类型在内存中的布局
    var i int = 10
    // 获取变量i的地址,&i
    fmt.Println("变量i的地址=", &i) // 打印:【变量i的地址= 0xc00000a0b8】

    /*
       说明:
       1.ptr是一个指针变量
       2.ptr的类型是*int
       3.ptr本身的值是&i
    */
    var ptr *int = &i
    // 获取ptr的值
    fmt.Printf("ptr=%v\n", ptr) //打印:【ptr=0xc00000a0b8】
    // 获取ptr的地址
    fmt.Println("ptr的地址=", &ptr) // 打印:【ptr的地址= 0xc00004e028】
    // 获取ptr指向的值
    fmt.Println("ptr指向的值=", *ptr) //  打印:【ptr指向的值=10】
}

1.4.2指针细节说明

  1. 值类型,都有对应的指针类型,形式为*数据类型,比如:int的对应指针就是 *int,float32对应的指针就是 *float32,以此类推;
  2. 值类型包括:基本数据类型int系列、float系列、bool、string、数组和结构体struct。

1.4.3 案例演示

  1. 写一个程序,获取int变量的num地址,并现在在终端;

  2. 将num的地址赋值给指针ptr,并通过ptr去修改num的值。

    func main() {
        var num int = 100
        fmt.Printf("变量num的地址=%v\n", &num)
        fmt.Println("num=", num)
    
        var ptr *int
        ptr = &num
        *ptr = 99
        fmt.Println("num=", num)
    }
    

1.4.4 值类型和引用类型

分类
  1. 值类型:基本数据类型int系列、float系列、bool、string、数组和结构体struct;
  2. 引用类型:指针、slice切片、map、管道chan、interface等都是引用类型。
使用特点
  1. 值类型:变量直接存储值,内存通常在栈中分配(值类型通过逃逸分析可能会跑到堆区);
  1. 引用类型:变量存储的就是一个地址,这个地址对应的空间才是真正的存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,改地址对应的数据空间就成为一个垃圾,由GC来回收。

1.5 系统保留关键字

在Go中,为了建华代码编译过程中对代码的的解析,其定义的保留关键字只有25个,详见如下:

breakdefaultfuncinterfaceselect
casedefergomapstruct
chanelsegotopackageswitch
constfallthroughifrangetype
continueforimportreturnvar

1.6系统预定义标识符

除了保留关键字外,Go还提供了36个预定的标识符,其中包括基础数据类型和系统内嵌函数:

appendboolbytecapclosecomplex
complex64complex128uint16copyfalsefloat32
float64imagintint8int16uint32
int32int64iotalenmakenew
nilpanicuint64printprintlnreal
recoverstringtrueuintuint8uinprt

1.7 命名规范

1.7.1 标识符概念

Golang对各种变量、方法、函数等命名时使用的字符序列称为标识符,只要是可以起名字的地方都叫标识符。

1.7.2标识符命名规范(⭐⭐⭐)

  1. 由26个应为字母大小写组成,0~9,"_"组成;
  2. 数字不可以开头;
  3. Golang中严格区分大小写;
  4. 标识符不能包含空格;
  5. 下划线"_"本身在Go中是一个特殊标识符,称为空标识符。可以代表任何其他的标识符,但是他对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用。
  6. 不能以系统保留关键字作为标识符,比如:break、if等…

1.7.3 注意事项

  1. 包名:和package名字和目录保持一致,尽量采取有意义的包名,不要和标准库有冲突;
  2. 变量名、函数名、常量名:采用驼峰写法;
  3. 如果变量名、函数名、常量名首字母大写,则可以被其他包访问;如果首字母小写,则只能在本包中使用(注:可以理解为首字母大写是公有的(public),首字母小写是私有的(private)),在Golang中没有public和private关键字

1.8运算符

运算符是一种特殊符号,用于表示数据的运算、赋值和比较等(类型:算数运算符、赋值运算符、比较运算符、逻辑运算符、位运算符、其他运算符);在Golang中,没有三元运算符,使用if…else…

细节说明

  1. Go中的自增自减只能当成一个独立的语言使用,不能这样使用:b := a++ 或 b := a-- ;
  2. Go的++和–只能卸载变量的后面,不能写在变量的前面,即:只有a++或a–,没有++a或–a ;
  3. Go的设计者去除了C/Java中的自增自减容易混淆的写法(强制性),使Golang更加简洁统一。
  • 18
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值