视频资源:b站UP主v若水若水的尚硅谷go视频

不动笔墨不读书 ,虽然我有全套视频和笔记 还是自己动点笔墨

因为在19年下半年大致学过go语言 所以这么计划:一个星期拿下基础 一个星期拿下框架 两个星期拿出项目 一个月搞定go

Go环境安装

版本选择

>go version
go version go1.13.5 windows/amd64

SDK:软件开发工具包。是提供给开发人员使用的,其中包含了对应开发语言的工具包

Go SDK下载地址:https://www.golangtc.com/download

src:go的源代码

bin: go的指令

Go开发需要配置的环境变量

  • GOROOT:指定SDK的安装 路径E:\GO
  • PATH:添加SDK的/bin目录 E:\GO\go\bin
  • GOPATH:工作目录,捡来go项目的工作路径 E:\gostudent

IDE: 选择goland https://www.cnblogs.com/zisefeizhu/p/11178668.htm

Go官方编程指南

Go 设计思想:一个问题尽量只有一个解决方法

Golang 官方网站 国内要使用特殊手段 https://golang.org

进入后第一个页面,点击 tour-> 选择 简体中文就可以进入中文版的 Go 编程指南

Golang 官方标准库 API 文档,https://golang.org/pkg可以查看 Golang所有包下的函数和使用

api : application program interface:应用程序编程接口。 就是我们 Go 的各个包的各个函数。

API是Golang提供的基本编程接口

Go语言提供了大量的标准库,因此Google公司也为这些标准库提供了相应的API文档,用于告诉开发者如何使用这些标准库,以及标准库包含的方法

Go中文网 在线标准库文档:https://studygolang.com/pkgdoc

Go的包和源文件和函数的关系简图

标识符的命名规范

Go对各种变量、方法、函数等命名时使用的字符序列称为标识符
凡是自己可以起名字的地方都叫标识符
由26个英文字母大小写,0-9,_组成
数字不可以开头。var num int // √ var 3num int//×
Go中严格区分大小写
var num int
var Num int
说明:在Go中,num和Num是两个不同的变量
标识符不能包含空格
下划线”_”本身在Go中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用
不能以系统保留关键字作为标识符(一共有25个),比如break,if 等等...
包名:保持package的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和标准库冲突
变量名、函数名、常量名:采用驼峰法
如果变量名、函数名、常量名首字母大写,则可以被其他的包访问:如果首字母小写,则只能在本包中使用(注:可以简单的理解成,首字母大写是公开的,首字母小写是私有的),在Go语言中没有public,private等关键字。
hello hello12 h_4 _ab int【建议不要使用】 float32【建议不要使用】 Abc 1hello h-b ‘x h’ _

系统保留关键字

在Go中,为了简化代码编译过程中对代码的解析,其定义的保留关键字只有25个

系统的预定义标识符

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

Go语言快速开发入门

hello.go

//开发一个hello.go程序,可以输出 "hello, 紫色飞猪"
package main import (
"fmt"
_"log"
) func main() {
fmt.Println("hello, zisefeizhu")
}
1) go文件的后缀是.go
2) package main
表示该hello.go文件所在的包是main。再go中,每个文件都必须归属于一个包 3) import "fmt"
表示:引入一个包,包名fmt,引入该包后,就可以使用fmt包的函数,比如:fmt.Println
fmt包中提供格式化、输出、输入的函数
4)_"log"
go语言定义的变量或者import的包如果没有使用到,就用_注释掉。
4) func main() { //func是关键字,表示一个函数
//main是函数名,是一个主函数,程序的入口
fmt.Println("hello,zisefeizhu") //表示调用fmt包的函数 Println输出“hello, zisefeizhu”
} 5) go语言严格区分大小写。
6) go编译器是按行进行编译的,一行写一条语句,每条语句不需要分号(go讨语言会在每行后自动加分号),不能把多行语句写在同一行
7) go语言大括号成对出现。

Go执行流程分析 go run / go build

E:\gostudent>dir                            //项目目录
E:\gostudent 的目录
2020/04/01 15:16 <DIR> .
2020/04/01 15:16 <DIR> ..
2020/04/01 15:33 <DIR> .idea
2020/04/01 15:33 <DIR> 2020-04-01 //今日目录 E:\gostudent>cd 2020-04-01
E:\gostudent\2020-04-01>dir
E:\gostudent\2020-04-01 的目录
2020/04/01 15:33 <DIR> .
2020/04/01 15:33 <DIR> ..
2020/04/01 15:33 151 hello.go //hello.go文件 E:\gostudent\2020-04-01>go run hello.go
hello, zisefeizhu //编译运行一步完成 E:\gostudent\2020-04-01>dir
E:\gostudent\2020-04-01 的目录
2020/04/01 15:33 <DIR> .
2020/04/01 15:33 <DIR> ..
2020/04/01 15:33 151 hello.go
1 个文件 151 字节
2 个目录 121,884,221,440 可用字节
//没有生成二进制文件 E:\gostudent\2020-04-01>go build hello.go E:\gostudent\2020-04-01>dir
驱动器 E 中的卷是 娱乐
卷的序列号是 78AB-12F2 E:\gostudent\2020-04-01 的目录 2020/04/01 15:49 <DIR> .
2020/04/01 15:49 <DIR> ..
2020/04/01 15:49 2,106,368 hello.exe //二进制文件
2020/04/01 15:33 151 hello.go
E:\gostudent\2020-04-01>hello.exe //直接执行
hello, zisefeizhu 1)如果先编译生成了可执行文件,那么可以将该可执行文件拷贝到没有go开发环境的机器上,仍然可以运行
2)如果是直接go run 源代码,那么如果要在另外一个机器上这么运行,也需要go开发环境,否则无法执行
3)在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变大了很多 go build 可以指定生成的可执行文件名
E:\gostudent\2020-04-01>go build -o zisefeizhu.exe hello.go E:\gostudent\2020-04-01>dir
2020/04/01 15:55 <DIR> .
2020/04/01 15:55 <DIR> ..
2020/04/01 15:49 2,106,368 hello.exe
2020/04/01 15:33 151 hello.go
2020/04/01 15:55 2,106,368 zisefeizhu.exe
3 个文件 4,212,887 字节
2 个目录 121,880,002,560 可用字节 E:\gostudent\2020-04-01>zisefeizhu.exe
hello, zisefeizhu windows 二进制文件必须是.exe linux 没有后缀之分

转义字符

//转义字符
package main
import "fmt"
func main() {
fmt.Println("hello\tzisefeizhu\nage\t21\ndir\tE:\\gostudent\\2020-04-01\nhellozisefeizhuhellozisefeizhu\rzisefeizhu\ni live you\"jing xiang\"")go
}
输出:
hello zisefeizhu
age 21
dir E:\gostudent\2020-04-01
zisefeizhu
i live you"jing xiang" 1)\t : 表示一个制表符,通常使用它可以排版
2)\n : 换行符
3)\\ : 一个\
4)\" : 一个 "
5)\r : 一个回车 不是换行 是整行替换了
在现实中,我们认为回车和换行是一码事,但是在计算机的世界里面其实我们之前的判断是有误的。回车是意味着当前行的返回到行首,而换行是结束本行到下一行。

注释

//注释
package main
import "fmt"
func main() {
//单行注释
/*
多行注释
多行注释
*/
fmt.Println("注释")
} 1) 对于行注释和块注释,被注释的文字,不会被Go编译器执行
2) 块注释里面不能有块注释,也就是说块注释不能有嵌套
3) 推荐使用单行注释

代码风格

package main
import "fmt"
func main() {
fmt.Println("gofmt格式化")
var num int = 2 + 4 * 5
fmt.Println("hellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisef" +
"eizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhu" +
"hellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozi" +
"sefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhuhellozisefeizhu\nnum = ",num)
} 1) 使用一次tab操作,实现缩进,默认整体向右边移动,使用shift+tab整体向左移
2) 使用gofmt来进行格式化
3) 运算符两边习惯性各加一个空格
4) 大括号必须和函数名同行
5) 一行最长不超过80个字符,超过的请使用换行展示,尽量保持格式优雅

Dos常用指令

dos的基本操作原理

案例:

切换到E盘,新建一个目录zisefeizhu,切换到该目录,新建 a b c 三个目录,切换到a 目录, 新建文件news.txt,复制文件到b目录下,移动到c目录下,最后都删除

e:\gostudent\2020-04-01>cd e:\   //切换到e盘
e:\>md zisefeihu //新建目录zisefeizhu
e:\>cd zisefeihu //切换到该目录
e:\zisefeihu>md a b c //新建目录 a b c
e:\zisefeihu>dir //查看目录下的内容
2020/04/01 16:55 <DIR> a
2020/04/01 16:55 <DIR> b
2020/04/01 16:55 <DIR> c
e:\zisefeihu>cd a //切换到a 目录 相对目录
e:\zisefeihu\a>echo . > news.txt //创建一个空文件
e:\zisefeihu\a>copy news.txt e:\zisefeihu\b //复制到b目录 绝对路径
已复制 1 个文件。
e:\zisefeihu\a>move news.txt e:\zisefeihu\c //移动到c盘
移动了 1 个文件。
e:\zisefeihu\a>dir
e:\zisefeihu\a>cd ..
e:\zisefeihu>cd ..
e:\>rd /q/s zisefeihu //删除zisefeizhu目录及子目录和文件 不带询问
e:\>dir
e:\>cls //清屏 cang lao shi :苍老师 首字母

Go变量

一个程序就是一个世界,变量是程序的基本组成单位。

变量相当于内存中一个数据存储空间的表示,可以把变量看作是一个房间的门牌号,通过门牌号可以找到房间,同样的道理,通过变量名可以访问到变量(值)

变量的使用步骤

import "fmt"
func main() {
var i int //声明变量(定义变量)
i = 10 //非变量赋值
fmt.Println("i = ", i) //使用变量
}
//i = 10
1) 变量表示内存中的一个存储区域
这里可以把内存比喻成一个大厦每个房间都是存储区域
2)该区域有自己的名称(变量名)和类型(数据类型)
房间号 房间存放的内容

变量使用三种方式:

func main()  {
var i int //指定变量类型,声明后如不赋值,使用默认值
var num = 10.11 //根据值自行判定变量类型(类型推导)
name := "zisefeizhu" //(3)省略var,注意:=左侧的变量不应该是已经声明过的,否则会导致编译错误
n1, n2, name2 := 100, 200, "jingxing" //一次性声明多个变量
} 一次性声明多个全局变量【在go中函数外部定义变量就是全局变量】
var (
n3 = 300
n4 = 900
name2 = "yike"
)
func main() {
}
变量在同一个作用域(在一个函数或者在代码块)内不能重名
变量 = 变量名 + 数据类型 + 值 【变量的三要素】
Go的变量如果没有赋初值,编译器会使用默认值,比如int 默认值0 string默认值是空串,小数默认值为0

变量的声明、初始化和赋值

声明变量
基本语法:var 变量名 数据类型
var a int 这就是声明了一个变量,变量名是a
var num1 float32 这也是声明了一个变量,表示一个单精度类型的小数,变量名是num1 初始化变量
在声明变量的时候,就给值
var a int = 45 这就是初始化变量a
使用细节:如果声明时就直接赋值,可省略数据类型
var b = 400 变量赋值
var num int //默认0
num = 780 这就是给变量赋值

程序中 + 号的使用

  1. 当左右两边都是数据型时,则做加法运算

    2) 当左右两边都是字符串,则做字符串拼接

数据类型的基本介绍

在 Go 编程语言中,数据类型用于声明函数和变量。数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。编译器在进行编译的时候,就要知道每个值的类型,这样编译器就知道要为这个值分配多少内存,并且知道这段分配的内存表示什么。

基本数据类型、数组和结构体都是值类型

整数类型

int的有符号类型

类型 有无符号【正负】 占用存储空间 表数范围 备注
int8 1字节 -128 ~ 127 -128 到 127
int16 2字节 -2^15 ~ 2^15 - 1 -32768 到 32767
int32 4字节 -2^31 ~ 2^31 -1 -2147483648 到2147483647
int64 8字节 -2^63 ~ 2^63 -1 -9223372036854775808 到 9223372036854775807

int的无符号类型

类型 有无符号 占用存储空间 表数范围 备注
uint8 1字节 0 ~ 255 0 到 255
uint16 2字节 0 ~ 2^16 - 1 0 到 65535
uint32 4字节 0 ~ 2^32 - 1 0 到 4294967295
uint64 8字节 0 ~ 2^64 4- 1 0 到 18446744073709551615

有无符号类型的区别

​ 首位为符号位

int的其它类型

类型 有无符号 占用存储空间 表数范围 备注
int 32位系统4个字节/64位系统8个字节 -2^31 ~ 2^31 - 1/-2^63 ~ 2^63 - 1
uint 32位系统4个字节/64位系统8个字节 0 ~ 2^32 - 1/0 ~ 2^64 - 1
rune 与int32一样 -2^31 ~ 2^31 - 1 Unicode码
uintptr 无符号整形,用于存放一个指针,是一种无符号的整数类型,没有指定具体的bit大小但是足以容纳指针。uintptr类型只有在底层编程是才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。
byte 与uint8等价 0 ~ 255 一般用来存储单个字符

整型的使用细节

package main

import (
"fmt"
"unsafe"
) func main() {
var n1 = 65535 //Golang的整型默认声明为int型
fmt.Printf("n1的类型是%T n1 占用的字节数是%d ", n1, unsafe.Sizeof(n1)) //在程序查看某个变量的字节大小和数据类型
}
//n1的类型是int n1 占用的字节数是8 Go程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型
bit:计算机中的最小存储单位。byte:计算机中基本存储单位。1byte = 8bit
有符号类型可以存储任何整数,无符号类型只能存储自然数
定义一个int8类型的整数(var num int8 = 0),如果一直自加1,这个变量的值会是(0...127 -128 -127... 0 ...127)循环往复下去,而不会超过类型最大值的范围

浮点数/小数类型

小数类型就是用于存放小数的,比如 6.6 0.23 -1.91

小数类型分类

类型 占用存储空间 表数范围
单精度float32 4字节 -3.403E38 ~ 3.403E38
双精度float64 8字节 -1.798E308 ~ 1.798E308
complex64 32位实数和虚数
complex128 64位实数和虚数
func main()  {
var n1 = 21.23 //默认声明为float64 推荐使用float64
var (
n2 float32 = -123.0000901 //float64的精度比float32高
n3 float64 = -123.0000901
)
fmt.Printf("n1的类型%T n1 占用的字节数是%d\n", n1, unsafe.Sizeof(n1))
fmt.Println("n2 = ",n2, "n3 = ",n3)
}
//n1的类型float64 n1 占用的字节数是8
//n2 = -123.00009 n3 = -123.0000901
尾数部分可能丢失,造成精度损失
浮点类型有固定的范围和字段长度,不受os影响
浮点数 = 符号位+指数位+尾数位
浮点数都是有符号的
浮点型常量有两种表示形式
十进制数形式:如:5.12 .512(必须有小数点)
科学计数法形式:如:5.1234e2 = 5.1234^10的2次方 5.12E-2 = 5.12/10的2次方

字符类型

Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。

字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的,也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的。

func main()  {
var (
c1 byte = 'a' //字符常量用单引号括起来
c2 byte = '0' //字符o byte等价uint8
//c3 byte = '北' //.\变量.go:12:13: constant 21271 overflows byte
//c3 int = "北" //.\变量.go:13:12: cannot use "北" (type string) as type int in assignment
c3 int = '北'
c4 int = 22269
n1 = 10 + c1 //字符类型是可以进行运算的
)
fmt.Printf("c2 的类型是%T c2占用的字节数%d c2对应的字符%c\n ", c2, unsafe.Sizeof(c2), c2)
fmt.Println("c1 = ", c1) //直接输出byte值,就是输出对应字符的码值。 字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值
fmt.Printf("c3 = %c c3对应码值=%d\n", c3, c3 ) //格式化输出对应的字符
fmt.Printf("c4 = %c\n", c4)
fmt.Println("n1 = ", n1) }
//c2 的类型是uint8 c2占用的字节数1 c2对应的字符0
// c1 = 97
//c3 = 北 c3对应码值=21271
//c4 = 国
//n1 = 107
Go语言的字符使用UTF-8编码,如果想查询字符对应的utf8码值:http://www.mytju.com/classcode/tools/encode_utf8.asp
英文字符 - 1个字节 汉字 - 3个字节 字符型存储到计算机中,需要将字符对应的码值(整数)找出来
存储:字符 -->对应码值 -->二进制 -->存储
读取:二进制 -->码值 -->字符 -->读取
字符和码值的对应关系是通过字符编码表决定的(是规定好的)
Go语言的编码都统一成了utf-8。非常的方便,很统一,再也没有编码乱码的困扰了

布尔类型

布尔类型也叫bool类型,bool类型数据只允许取值true和false

bool类型占1个字节

bool类型适于逻辑运算,一般用于程序流程控制

if条件控制语句

for循环控制语句

func main()  {
var b = false
fmt.Printf("b = %v, b的占用空间=%d", b, unsafe.Sizeof(b))
}
//b = false, b的占用空间=1

string类型

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

func main()  {
var (
addrress string = "北京 110 world!"
str = "hello" // // 字符串一旦赋值了,字符串就不能修改了:在Go中字符串是不可变的
)
str2 := `str[0] = 'a'` //反引号,会识别转义字符,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击,输出源代码等效果
fmt.Println("str2 = ", str2, "\n","address = ", addrress)
}
//str2 = str[0] = 'a'
// address = 北京 110 world!

基本数据类型的默认值

在go中,数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值,在Go中,默认值又叫o值

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

基本数据类型的相互转换

Go在不同类型的变量之间赋值时需要显式转换。也就是说Go中数据类型不能自动转换

func main()  {
var (
i int32 = 1000 //被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化
n1 float32 = float32(i)
n2 int8 = int8(i) //将int32转成int8【-128 - 127】,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。因此在转换时,需要考虑范围
n3 int64 = int64(i)
)
n4 = i + n2 //类型不同,不能相加
fmt.Printf("i = %v, n1 = %v, n2 = %v, n3 = %v", i, n1, n2, n3)
}
//i = 1000, n1 = 1000, n2 = -24, n3 = 1000 表达式T(v)将值v转换为类型T
T:就是数据类型,比如int32, int64, float32 等等
v:就是需要转换的变量
Go中,数据类型的转换可以是从:表示范围小 --> 表示范围大,也可以:范围大 --> 范围小 存在溢出现象

基本数据类型和string的转换

在程序开发中,经常将基本数据类型转成string,或者将string转成基本数据类型

基本类型转string类型

func main()  {
var (
num1 int = 99
num2 float32 = 23.456
b bool = true
myChar byte = 'h'
str string //空的str
)
//使用第一种方式来转换fmt.Sprintf方法 fmt.Sprintf("%参数",表达式)
//参数需要和表达式的数据类型相匹配
//fmt.Sprintf() 会返回转换后的字符串
str = fmt.Sprintf("%d",num1) //%d 表示为十进制
fmt.Printf("str type %T str = %q\n",str,str) //%T 值的类型的Go语法表示
// %q 该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示 str = fmt.Sprintf("%f",num2) //%f 有小数部分但无指数部分,如123.456
fmt.Printf("str type %T str = %q\n",str,str) str = fmt.Sprintf("%t",b)
fmt.Printf("str type %T str = %q\n",str,str) str = fmt.Sprintf("%c",myChar) //%c 该值对应的unicode码值
fmt.Printf("str type %T str = %q\n",str,str)
}
//str type string str = "99"
//str type string str = "23.455999"
//str type string str = "true"
//str type string str = "h" 这也是我喜欢用的一种 简单好使

func main()  {
//第二种方式strconv函数
var (
num3 int = 99
num4 float64 = 23.456
b2 bool = true
str string
)
str = strconv.FormatInt(int64(num3),10) //这里的10是进制
fmt.Printf("str type %T str = %q\n",str,str)
//strconv.FormatFloat(num4,'f',10,64)
//说明:'f'格式 10:表示小数位保留10位,64:表示这个小数是float64
str = strconv.FormatFloat(num4,'f',10,64)
fmt.Printf("str type %T str = %q\n",str,str) str = strconv.FormatBool(b2)
fmt.Printf("str type %T str = %q\n",str,str)
//strconv包中有一个函数Itoa
var num5 int64 = 4567
str = strconv.Itoa(int(num5)) //strconv.Itoa是strconv.FormatInt的简写
fmt.Printf("str type %T str = %q\n",str,str)
}
//str type string str = "99"
//str type string str = "23.4560000000"
//str type string str = "true"
//str type string str = "4567" 函数将浮点数表示为字符串并返回。
bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入。
fmt表示格式:'f'(-ddd.dddd)、'b'(-ddddp±ddd,指数为二进制)、'e'(-d.dddde±dd,十进制指数)、'E'(-d.ddddE±dd,十进制指数)、'g'(指数很大时用'e'格式,否则'f'格式)、'G'(指数很大时用'E'格式,否则'f'格式)。
prec控制精度(排除指数部分):对'f'、'e'、'E',它表示小数点后的数字个数;对'g'、'G',它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。

string类型转基本数据类型

func main()  {
var (
str string = "true"
b bool
str2 string = "1234590"
n1 int64
n2 int
str3 string = "123.456"
f1 float64
str4 string = "hello"
n int64 = 11
)
//b,_ = strconv.ParseBool(str)
//说明
//1. strconv.ParseBool(str)函数会返回两个值(value bool,err error)
//2. 因为只想获取到value bool,不想获取err所以使用_忽略
b,_ = strconv.ParseBool(str)
fmt.Printf("b type %T b = %v \n",b,b)
n1,_ = strconv.ParseInt(str2,10,64)
n2 = int(n1)
fmt.Printf("n1 type %T n1 = %v\n",n1,n1)
n3 := int32(n1)
fmt.Printf("n3 type %T n3 = %v\n", n3,n3) //再将64位转32位
fmt.Printf("n2 type %T n2 = %v\n",n2,n2)
f1,_ = strconv.ParseFloat(str3,64)
fmt.Printf("f1 type %T f1 = %v\n",f1,f1)
n, _ = strconv.ParseInt(str4, 10, 64)
//在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据,比如我们可以把’123’转成一个整数,
//但是不能把“hello”转成一个整数,如果这样做,Go直接将其转成0,其它类型也是一样的道理。
// float --> 0 bool --> false
fmt.Printf("n type %T n == %v\n", n,n)
}
//b type bool b = true
//n1 type int64 n1 = 1234590
//n2 type int n2 = 1234590
//f1 type float64 f1 = 123.456
//n type int64 n == 0

值类型和引用类型

值类型:基本数据类型int系列、float系列、bool、string、数组和结构体struct

引用类型:指针、slice切片、map、管道chan、interface等都是引用类型

值类型和引用类型的使用特点

值类型:变量直接存储值,内存通常在栈中分配

引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收

内存的栈区和堆区示意图

指针

基本数据类型,变量存的就是值,也叫值类型

获取变量的地址,用&,比如:var num int,获取num的地址:&num

分析一下基本数据类型在内存的布局

func main()  {
//基本数据类型,变量存的就是值,也叫值类型
var i int = 10
fmt.Println("i 的地址 = ", &i) //获取变量的地址,用&,比如:var num int,获取num的地址:&num var ptr *int = &i //指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值
//1. ptr 是一个指针变量
//2. ptr 的类型 *int
//3. ptr 本身的值&i
*ptr = 101
fmt.Printf("ptr = %v\n", ptr)
fmt.Printf("ptr的地址 = %v\n", &ptr)
fmt.Printf("ptr 指定的值 = %v\n", *ptr) //获取指针类型所指向的值,使用:*,比如:var ptr *int,使用*ptr获取ptr指向的值
fmt.Printf("i 的值 =%v", i) //将i的地址赋给指针ptr,并通过ptr去修改i的值
}
//i 的地址 = 0xc00000a0b8
//ptr = 0xc00000a0b8
//ptr的地址 = 0xc000006030
//ptr 指定的值 = 101
//i 的值 =101 值类型,都有对应的指针类型,形式为 *数据类型,比如int的对应的指针就是 *int,float32对应的指针类型就是*float32,依次类推
值类型包括:基本数据类型int系列、float系列、bool、string、数组和结构体struct

go语言系列-从零到数据类型的基本介绍的更多相关文章

  1. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

  2. Go语言系列(三)之数组和切片

    <Go语言系列文章> Go语言系列(一)之Go的安装和使用 Go语言系列(二)之基础语法总结 1. 数组 数组用于存储若干个相同类型的变量的集合.数组中每个变量称为数组的元素,每个元素都有 ...

  3. C++语言编译系统提供的内部数据类型的自动隐式转换

    C++语言编译系统提供的内部数据类型的自动隐式转换规则如下: 程序在执行算术运算时,低类型自动隐式转换为高类型. 在函数调用时,将实参值赋给形参,系统隐式的将实参转换为形参的类型,并赋值给形参. 函数 ...

  4. R语言系列:生成数据

    R语言系列:生成数据 (2014-05-04 17:41:57) 转载▼ 标签: r语言 教育 分类: 生物信息 生成规则数据1.使用“:“,如x=1:10,注意该方法既可以递增也可以递减,如y=10 ...

  5. Symbol -- JavaScript 语言的第七种数据类型

    ES5 的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突.如果有一种机制,保证 ...

  6. OpenCV学习系列(零) Mac下OpenCV + xcode环境搭建

    # OpenCV学习系列(零) Mac下OpenCV + xcode环境搭建 [-= 博客目录 =-] 1-学习目标 1.1-本章介绍 1.2-实践内容 1.3-相关说明 2-学习过程 2.1-hom ...

  7. 采用C/C++语言如何实现复数抽象数据类型Complex

    记录一下! 采用C/C++语言如何实现复数抽象数据类型Complex #include <stdio.h> typedef struct Complex { double e1; // 实 ...

  8. Go语言系列开发之延迟调用和作用域

    Hello,各位小伙伴大家好,我是小栈君,最近一段时间我们将继续分享关于go语言基础系列,当然后期小栈君已经在筹划关于java.Python,数据分析.人工智能和大数据等相关系列文章.希望能和大家一起 ...

  9. 00.从0实现一个JVM语言系列

    00.一个JVM语言的诞生 由于方才才获悉博客园文章默认不放在首页的, 原创文章主要通过随笔显示, 所以将文章迁移到随笔; 这篇帖子将后续更新, 欢迎关注! 这段时间要忙着春招实习, 所以项目更新会慢 ...

随机推荐

  1. TDA2050功率放大器研究

    音频功率放大模块(以下简称功放)用于处理模拟信号,将功率较低的输入信号进行线性放大,输出大功率的信号以驱动换能器.通常,电子发烧友自己设计功放,与各类音源和喇叭匹配,以得到满意的音响效果.在测试中,实 ...

  2. 分享一个快速审查js操作Dom的css

    第一步 打开开发者工具第二步 打开 Sources 面板第三步 执行用户操作让对象可见(例如鼠标悬停)第四步 在元素可见的时候按下 F8(与“暂停脚本执行”按钮相同)第五步 点击开发者工具左上角的“选 ...

  3. Flink系列之状态及检查点

    Flink不同于其他实时计算的框架之处是它可以提供针对不同的状态进行编程和计算.本篇文章的主要思路如下,大家可以选择性阅读. 1. Flink的状态分类及不同点. 2. Flink针对不同的状态进行编 ...

  4. openwrt MT7620A MT7610E 5G 驱动添加移值

    使用 github 上别人提供好的源码.整合到最新的 openwrt 18 中,目前 kernel 的版本为 4.1 . 编辑中....

  5. HTML5&CCS3(2) 处理网页文件

    2.1 规划网站 为什么要创建这个站点,需要展示的内容是什么? 应该如何调整内容使之吸引期望的访问者? 需要多少个页面?网站的结构是怎样? 为页面.图像和其他外部文件设计一个简单且一致的命名规则. 2 ...

  6. ES6中的find与filter的区别

    一直以来以为find和filter是一样的效果,最近在梳理,才发现是不一样的. 首先,filter和find区别:filter返回的是数组,find返回的是对象. 注意:find()找到第一个元素后就 ...

  7. git常规使用命令笔记

    使用git也有不短的时间,这篇文章主要默写自己在提交代码经常使用的一些密令,仅供参考并不是教程. git log 查看日志 git branch 查看分值 git branch Name 新建一个Na ...

  8. 初学react

    React特点: 声明式设计:建议使用JSX来描述用户界面;构建组件:单向响应的数据流: JSX:JSX是一种JAVASCRIPT的语法扩展,元素是构成react的最小单位,JSX就是用来声明REAC ...

  9. 分布式框架Celery(转)

    一.简介 Celery是一个异步任务的调度工具. Celery 是 Distributed Task Queue,分布式任务队列,分布式决定了可以有多个 worker 的存在,队列表示其是异步操作,即 ...

  10. Hadoop集群搭建(二)~centos6.8的安装

    这篇记录在创建好的虚拟机中安装centos6.8 1,在虚拟机界面-选择编辑虚拟机设置 2,CD/DVD,选择使用ISO映像文件,找到安装包的位置,确定 3,回到虚拟机的界面,开启此虚拟机 4,安装 ...