go语言干货(需要有一定编程经验)(体系梳理)(语法速查)(自带实战项目)

go 专栏收录该内容
2 篇文章 0 订阅

go是强类型判断的静态语言。

1、安装go

google官方go语言下载安装地址直链

作者用的是brew安装的。

brew install go

brew的方式安装完会出现下面两个目录:

/usr/local/Cellar/go

~/go

使用IDEA GoLand会发现自动帮我们查找到了

GOROOT=/usr/local/Cellar/go/1.12.6/libexec
GOPATH=/Users/jenrey/go

如果没有请自行配置环境变量。

2、Go语言数据类型思维导图

3、变量

变量相当于是内存中的一块数据,是一块存储空间,可以通过定义一个变量来申请一块数据存储空间,之后可以通过所定义的变量名来操作我们申请的这块存储空间。可以说变量是我们编写的程序的一个最基本的组成单元或者叫组成单位。

  1. 变量是内存中的一块存储空间
  2. 通过定义变量申请存储空间

变量定义未赋值时的默认值

int 0
int8 0
int32 0
int64 0
rune 0 // rune 的实际类型是 int32
float32 0 // 长度为 4 byte
float64 0 // 长度为 8 byte
bool false
string “”

变量的声明方式 

// 不赋值有默认的零值(根据数据类型来确定零值)
var variables1 int    // 0

// 简短声明(要求这个变量之前没有被声明过)
variables2 := "我是jenrey"

// var variables = value 形式
var variables3 = 100    //这种情况,编译器自动做类型推导

// 一次赋值多个值
var variables4,variables5,variables6,variables7 = 1,"我是jenrey",3.14,true

// 简短声明,多次赋值
variables4,variables5,variables6,variables7 := 1,"我是jenrey",3.14,true

// 申请多个全局变量,在函数体外部

var (
   variablesx int
   slicex []int
   interfacex interface{}
)

// 变量的交换
var i = 100
var j = 200
fmt.Println(i,j)
i,j = j,i
fmt.Println(i,j)

/*
1、变量未必不需要添加分号;
2、变量的交换 i,j = j,i
3、Go 对于已声明但未使用的变量会在编译阶段报错
*/

var index int
//如果一个变量暂时不使用,可以赋值给他自己 
index = index

// _(下划线)是个特殊的变量名,任何赋予它的值都会被丢弃。
_,x := 122,211
fmt.Println(x)

/*
大写字母开头的变量是可导出的,即其它包(后面会讲到)可以读取的,是公有变量(相当于传统编程语言中class的public权限修饰符);
小写字母开头的就是不可导出的,是私有变量,仅本包可以使用(相当于传统编程语言中class的private权限修饰符)。
*/

4、常量

当程序中需要引入一个在整个程序运行期,数据不发生改变时,使用常量;

就是在程序运行期不可以改变的变量;

全局唯一,编译期就已经确定的值,提高程序执行效率;

Go 语言预定义常量

  1. true 
  2. false 
  3. iota

常量的声明方式 

// const constVariables 变量类型 = 变量值
const constVariables1 float64 = 3.1415926

// 一次申明多个值
const constVariables2,constVariables3 = 100,"jenrey"
fmt.Println(constVariables1,constVariables2,constVariables3)

// const (…)
const (
   iotaVariables1 = iota  //0
   iotaVariables2 = iota  //1
   iotaVariables3 = iota  //2
)

// 单独赋值
const iotaVariables4 = iota //0

// const 指定第一个iota,其余自动递增
const (
   iotaVariables5 = iota //0
   iotaVariables6        //1
   iotaVariables7        //2
)

// 枚举一周的日期
const (
   Monday = iota    //0
   Tuesday          //1
   Wednesday        //2
   Thursday         //3
   Friday           //4
   Saturday         //5
   Sunday           //6
)

// 同一行定义
const(
   iotaVariables8,iotaVariables9,iotaVariables10 = iota,iota,iota  // 打印出来全是0
)

// const中iota与iota之间跳过
const (
   iotaVariables11 = iota     //0
   iotaVariables12 = "jenrey" //jenrey
   iotaVariables13 = iota     //2
)

/*
1.通过const关键字来申请
2.常量是指编译期间就明确知道的值并且不可改变
3.iota比较特殊,iota在每个const出现时被重置为0;再下一个const出现之前每一个iota会自动+1
*/

5、整数类型(数值类型)

我们要存储一个人的年龄,就需要用到数值类型;

用于定义整数类型变量的标识符;

作用与应用场景:在计算机当中存储数值类型;

不同数值类型与占用的空间

// 有符号位
// 一个字节占用8位
int8     //占用1个字节    数据范围:-2^7到2^7-1
int16    //占用2个字节    数据范围:-2^15到2^15-1
int32    //占用4个字节    数据范围:-2^31到2^31-1
int64    //占用8个字节    数据范围:-2^63到2^63-1

// 无符号位,即最高位是正数
// 一个字节占用8位
uint8    //占用1个字节    数据范围:0到2^8-1
uint16   //占用2个字节    数据范围:0到2^16-1
uint32   //占用4个字节    数据范围:0到2^32-1
uint64   //占用8个字节    数据范围:0到2^64-1


/*
(重点注意!!!)默认数据类型为int
int32,int64由于占用空间大小不一样,被认为是不同的类型,所有不能相互赋值
不同类型的转换
占用字节 unsafe.Sizeof(intVariables)
注意使用时数据可能溢出与损失的问题
int的占内存大小是根据你系统的位数默认的。比如win10 64位系统 int就会默认int64,32位系统 int就会默认是int32。
*/

数值类型的声明方式

var intVariables1 = 100 //int类型 不指定数据类型默认是int类型
intVariables2 := 200 //int类型
var intVariables3 int32 //int32类型 没赋值默认是0
intVariables := 126 //int类型

//类型转换
intVariables3 = int32(intVariables) // 如果不转换会报错因为intVariables是int,intVariables3时int32类型,因为占用的大小不一样就是不同的数据类型。小类型转大类型没问题,大转小精度会丢失,这一点要考虑

//指定类型
var intVariables4 int64 = 123456789
fmt.Printf("intVariables1=%T,intVariables2=%T,intVariables3=%T\n",intVariables1,intVariables2,intVariables3)    //intVariables1=int,intVariables2=int,intVariables2=int32

//引入unsafe包,打印占据的空间大小,即字节大小
fmt.Println(unsafe.Sizeof(intVariables4))    // 8

tips:%T是格式化输出,值的类型的Go语法表示

6、浮点类型

当我们需要存储带有小数点的数据类型时需要使用浮点类型;

比如在小程序支付时,这里支付的金额,可能是1888.856元,这个时候就需要使用浮点类型;

  1. 单精度 float32
  2. 双精度 float64(默认)

tips:

float32类似C语言的float类型;

float64类似C语言的double类型;

推荐使用float64,因为比float32精度高。go语言中默认的浮点数类型就是float64。

注意没有float这种类型, 默认是float64;

浮点类型的声明方式

/*
float32 4个字节
float64 8个字节
*/

// 十进制的形式来展示
var floatVariables1 float32 = 3.1415926
floatVariables2 := .1416926                               // 0.1416926
fmt.Printf("floatVariables1的类型=%T,占用的字节大小=%d\n",floatVariables1,unsafe.Sizeof(floatVariables1))    // floatVariables1的类型=float32,占用的字节大小=4
fmt.Printf("floatVariables2的类型=%T,占用的字节大小=%d\n",floatVariables2,unsafe.Sizeof(floatVariables2))    // floatVariables2的类型=float64,占用的字节大小=8

// 科学计数法来展示
floatVariables3 := 3.1415926e2                            // e2代表3.1415926乘以10的2次方
floatVariables4 := 3.1415926e-2                           // e-2代表3.1415926除以10的2次方
fmt.Println(floatVariables3,floatVariables4)              // 314.15926 0.031415926

// 不同精度的浮点类型的转换
var floatVariables5 float32 = 3.14
var floatVariables6 float64 = 3.14
floatVariables6 = float64(floatVariables5)                // 在go中不能直接赋值,需要强制类型转换。注意大赋值给小存在的精度损失问题。
floatVariables6 = floatVariables6                         // 在go语言中如果这个变量暂时不使用,可以把变量赋值给本身。

/*
1.默认数据类型为float64
2.float32,float64由于占用空间大小不一样,被认为是不同的类型
3.不同类型的转换
4.单精度,双精度类型转换的精度损失与溢出
*/

复数

可以归类到浮点类型中。

表现形式:

实数+虚数i

  • complex64    (32 位实数 + 32 位虚数+i虚数单位)
  • complex128(默认)(64 位实数 + 64 位虚数+i虚数单位)

复数的声明方式

var complexVariables1 complex64
complexVariables1 = 3.14+12i
complexVariables2 := complex(3.14,12)    // 这里的complex是一个方法

fmt.Printf("complexVariables1的类型=%T,值=%v\n",complexVariables1,complexVariables1)    // complexVariables1的类型=complex64,值=(3.14+12i)
fmt.Printf("complexVariables2的类型=%T,值=%v\n",complexVariables2,complexVariables2)    // complexVariables2的类型=complex128,值=(3.14+12i)

//打印复数的实数部分与虚数部分
fmt.Println(real(complexVariables1),imag(complexVariables1))    // 3.14 12
//(实数部分用real方法,虚数部分用imag方法)

7、字符

字符是电子计算机中字母、数字、符号的统称,是数据结构中最小的数据存取单位,通常由8个二进制位(一个字节)来表示一个字符。

作用:用于存储单个字符

  • byte(是uint8的别名):占用1个字节,无符号,是ascii的一个字符,代表UTF8字符串的单个字节值。
  • rune(是int32的别名):代表单个unicode的字符。当需要处理中文、日文或者其他复合字符时,则需要用到 rune 类型,rune 类型是 int32 类型的别名。

Go语言中并没有字符这种数据类型;

字符的声明方式

/*
byte(uint8) byte 类型是 uint8 的别名
rune 类型,代表一个 UTF-8 字符,当需要处理中文、日文或者其他复合字符时,则需要用到 rune 类型,rune 类型是 int32 类型的别名
*/

var charVariables1 byte = '0'
charVariables2 := '波'
// var charVariables3 byte = '波'  // 这里取消注释会报错 constant 27874 overflows byte,中文翻译就是'波'这个字符超过了byte的限制。

fmt.Printf("charVariables1 = %d,charVariables2=%d\n",charVariables1,charVariables2)    // charVariables1 = 48,charVariables2=27874
fmt.Printf("charVariables2=%c,charVariables2=%T\n",charVariables2,charVariables2)    // charVariables2=波,charVariables2=int32 (也就是rune,因为'波'的ascii码值超过了字节类型表示的范围,所以go语言编译器自动帮我们推导成了int32)
// fmt.Printf("charVariables3=%c,charVariables3=%T\n",charVariables3,charVariables3)    // 这里取消注释会报错 constant 27874 overflows byte,中文翻译就是'波'这个字符超过了byte的限制。
variables := 'a' //对应的编码值
fmt.Printf("加和=%d,a的编码值=%d\n",100+variables,variables)    // 加和=197,a的编码值=97

/*
1.单引号括起来
2.在计算机中存储:字符 -> ascii码值 -> 二进制
3.读取:二进制 -> ascii码值 -> 字符
4.一个字符占一个字节,一个中文占3个字节
5.字符可以与整数进行算术运算(转成ascii码值再计算)
*/

8、字符串

字符串是的类型标识为string, 由数字、字母、下划线组成的一串字符。 在编程语言中用于表示文本的数据类型。

在go语言中,字符串都是以字节的方式组织起来的,默认使用的是utf-8编码,go语言有自己的字符串类型string。

Tips:

在go语言中字符串初始化后不允许对其重新赋值;

go的源码都是以UTF-8编码存在的,当你的源代码中如果包含中文,需要将原文件的存储格式转化成UTF-8

字符串的声明方式

// 申明并赋值,字符串需要使用双引号
var stringVariables1 string
stringVariables1 = "hello jenrey博客\n"

// 通过反引号定义,原样输出
var stringVariables2 = `
    hi~jenrey
    jenrey
    go
`
fmt.Printf("stringVariables1=%T,stringVariables2=%T", stringVariables1, stringVariables2)    // stringVariables1=string,stringVariables2=string
fmt.Printf("stringVariables1=%v,stringVariables2=%v", stringVariables1, stringVariables2)    // hello jenrey博客
//, stringVariables2=
//    hi~jenrey
//    jenrey
//    go

// 获取字符串长度
var stringVariables3 = "hello go,我是jenrey"
fmt.Println(len(stringVariables3))    // 21

// 在go语言中字符串初始化后不允许对其重新赋值
// stringVariables1[1] = 1    // 报错Cannot assign to stringVariables1[1]

// 字符串与字符串相加实际上就是字符串的拼接
fmt.Println("hello"+"j哥")    // helloj哥

/*
    遍历字符串
        方式一:以字节数组的形式
                使用len方法先获取到字符串的长度,而后用for遍历。
*/
stringVariables3Len := len(stringVariables3)
for index := 0; index < stringVariables3Len;index++ {
   // 这种情况如果是中文,则会有编码问题(注意看‘我是’两个字的中文输出的值有问题!)
   // 这是因为一个中文占用3个字节,这种以字节方式打印就会出现编码问题
   fmt.Printf("%s-编码值=%d,值=%c,类型=%T\n",stringVariables3,stringVariables3[index],stringVariables3[index],stringVariables3[index])
}
/*    输出结果:
hello go,我是jenrey-编码值=104,值=h,类型=uint8
hello go,我是jenrey-编码值=101,值=e,类型=uint8
hello go,我是jenrey-编码值=108,值=l,类型=uint8
hello go,我是jenrey-编码值=108,值=l,类型=uint8
hello go,我是jenrey-编码值=111,值=o,类型=uint8
hello go,我是jenrey-编码值=32,值= ,类型=uint8
hello go,我是jenrey-编码值=103,值=g,类型=uint8
hello go,我是jenrey-编码值=111,值=o,类型=uint8
hello go,我是jenrey-编码值=44,值=,,类型=uint8
hello go,我是jenrey-编码值=230,值=æ,类型=uint8
hello go,我是jenrey-编码值=136,值=,类型=uint8
hello go,我是jenrey-编码值=145,值=,类型=uint8
hello go,我是jenrey-编码值=230,值=æ,类型=uint8
hello go,我是jenrey-编码值=152,值=,类型=uint8
hello go,我是jenrey-编码值=175,值=¯,类型=uint8
hello go,我是jenrey-编码值=106,值=j,类型=uint8
hello go,我是jenrey-编码值=101,值=e,类型=uint8
hello go,我是jenrey-编码值=110,值=n,类型=uint8
hello go,我是jenrey-编码值=114,值=r,类型=uint8
hello go,我是jenrey-编码值=101,值=e,类型=uint8
hello go,我是jenrey-编码值=121,值=y,类型=uint8
*/

/*
    遍历字符串
        方式二:通过for..range 形式来遍历
                是go语言特有的,除了遍历字符串还可以遍历数组。
*/
// 通过range,在这种情况下中文就不会有问题,按照rune类型来打印
for index, val := range stringVariables3 {
   fmt.Printf("通过for index ... %s--索引:%d--字符值:%c--字符值类型;%T\n", stringVariables5, index, val, val) //val 的类型为 rune,即int32
}
/*    输出结果:
通过for index ... hello go,我是jenrey--索引:0--字符值:h--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:1--字符值:e--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:2--字符值:l--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:3--字符值:l--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:4--字符值:o--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:5--字符值: --字符值类型;int32
通过for index ... hello go,我是jenrey--索引:6--字符值:g--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:7--字符值:o--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:8--字符值:,--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:9--字符值:我--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:12--字符值:是--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:15--字符值:j--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:16--字符值:e--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:17--字符值:n--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:18--字符值:r--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:19--字符值:e--字符值类型;int32
通过for index ... hello go,我是jenrey--索引:20--字符值:y--字符值类型;int32
*/

// 针对for range我们也可以忽略index
for _, val := range stringVariables3 {
    fmt.Printf("%s-字符值=%d,值=%c\n", stringVariables3, val, val) // val 的类型为 rune,即int32
	}
/*    输出结果:
hello go,我是jenrey-字符值=104,值=h
hello go,我是jenrey-字符值=101,值=e
hello go,我是jenrey-字符值=108,值=l
hello go,我是jenrey-字符值=108,值=l
hello go,我是jenrey-字符值=111,值=o
hello go,我是jenrey-字符值=32,值= 
hello go,我是jenrey-字符值=103,值=g
hello go,我是jenrey-字符值=111,值=o
hello go,我是jenrey-字符值=44,值=,
hello go,我是jenrey-字符值=25105,值=我
hello go,我是jenrey-字符值=26159,值=是
hello go,我是jenrey-字符值=106,值=j
hello go,我是jenrey-字符值=101,值=e
hello go,我是jenrey-字符值=110,值=n
hello go,我是jenrey-字符值=114,值=r
hello go,我是jenrey-字符值=101,值=e
hello go,我是jenrey-字符值=121,值=y
*/

/*
1.双引号括起来
2.`` 反引号原样输出
3.字符串初始化之后不允许重新赋值
4.可以以字符数组下标的形式来读取,但不能赋值
5.len获取字符串长度
6.字符串相加即是拼接
*/

Tips:

for循环遍历值的类型为uint8
for...range遍历值的类型为int32

9、布尔类型

布尔类型,要么为真,要么为假。

  • 真 true
  • 假 false(默认情况下如果不赋值,默认为false)

在计算机当中,为了表示某个条件是否成立,需要使用到布尔类型;

应用于在条件判断当中,条件成立或条件不成立;

布尔类型的声明方式

var boolVaraibles1 bool
boolVaraibles1 = true
boolVaraibles2 := (true == false)

fmt.Println(boolVaraibles1, boolVaraibles2)    // true false

if 3 == 4 {
   fmt.Println("false")
} else {
   fmt.Println("true")    // true
}

fmt.Println(!true,!false,!!true)    // false true true

/*
1.只有true和false
2.其他类型不可以转换成布尔
3.go不支持=== 在PHP中判断两个数是否相等除了要判断类型还要判断值。因为go语言任何变量都有实际的类型,我们就不需要三个=来判断了。
*/

10、指针

语法:

  • 取地址操作符&,一般在指针操作当中经常使用,&取出地址
  • 取值操作符*,一般在指针操作当中,*根据地址找该地址指向空间的值。

程序在内存中存储它的值,每个内存块都 有一个地址,而存储这个地址的变量被称为指针变量,指针。
通常用十六进制数表示,如:0x6b0820 或 0xf84001d7f0

一个指针变量可以指向任何一个值的内存地址 它指向那个值的内存地址,在 32 位机器上占用 4 个字节,在 64 位机器上占用 8 个字节,并且与它所指向的值的大小无关。
指针可以指向任何类型的值,但是使用时指定指针的类型在实际编码中具有重要意义;
在指针类型前面加上 * 号来获取指针所指向的内容。
使用一个指针引用一个值被称为间接引用。

  • 1.主要用于管理内存
  • 2.指针是一个特殊的变量
  • 3.存储的是另一个变量的内存地址
  • 4.指针内存示意图

作用:

  • 节省内存空间,提高执行效率(当操作的数据量较大规模时)
  • 访问变量的值

应用场景:

  • 修改变量的值
  • 访问变量的值

野指针:

某一个内存空间已经释放了,但是我们另一个程序还在使用这块内存,在这种情况下就会导致内存的泄漏,这种情况下的指针就被称为野指针。

指针变量操作(怎么使用)

// 先定义变量,再定义指针去取变量的地址,那么这个变量存储的就是地址,实际的值是这个地址指向的空间

//先定义变量,再定义指针去取变量的地址
var intVariables int = 100
fmt.Printf("intVariables的值=%d,地址=%v\n",intVariables,&intVariables)    // intVariables的值=100,地址=0xc00006c008


//定义一个指针类型的变量,那么这个变量存储的就是地址,实际的值是这个地址指向的空间
//定义一个指针类型的变量去指向 intVariables
var pointerVariables *int = &intVariables
fmt.Printf("pointerVariables的值=%v,地址=%v\n",pointerVariables,&pointerVariables)    // pointerVariables的值=0xc00006c008,地址=0xc00007c020

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

格式化输出

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值