一.配置环境
1.安装go环境
环境:window10
下载go:https://golang.google.cn/dl/
2.解压,配置系统环境变量
GOPATH:安装的工具目录
2.安装VSCode以及插件,配置go环境
1.安装VSCode:下载–>执行exe即可
2.安装go环境插件
code Runner插件:每次执行,清除上次执行记录
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn
二.
1.基本指令
1.go build xx.go可以生成一个二进制的可执行文件
2.go run xx.go 也可以执行
2.注释
//单行注释
/*多行注释*/
3.go特点
1.后缀名为.go
2.go程序区分大小写
3.go定义的变量,或者import包,必须使用,如果没有会报错
4.go的语句后,不需要带分号
5.go中,不要把多条语句放在同一行。否则报错
6.go中的大括号成对出现,而且风格
func main(){
//语句
}
package main //表示hllo.go文件所在的包是main,在go中,每个文件都必须归属一个包
import "fmt" //进入一个包,包名fmt.
func main() { //func 是一个关键字,表示一个函数;main是函数名,是一个主函数,即程序入口
//fmt.Println("hello,world!") //表示调用fmt包的函数Println输出hello,world
fmt.Println("hell\tword") //"\t"作用
fmt.Println("my\"name") //" \" "作用
fmt.Println("dddd\\cccc") // "\\"作用
fmt.Println("dwdwd\rdwdwd") //"\r"作用,回车键功能
fmt.Println("dwdwad\nswdwd") //"\n"作用,换行
fmt.Println("姓名\t年龄\t籍贯\t住址\njone\t12\t河北\t北京")
}
执行结果:
第三章:Golang变
一.go变量的三种方式
1.第一种:指定变量类型,声明后若不赋值,使用默认值
2.第二种:根据值自行判断变量类型
3.第三种:省略var,注意:=左侧的变量不应该是已经声明过的。
二.多变量
1.多变量
2.全局变量
3.5变量的声明,初始化和赋值
声明变量
基本语法:var 变量名 数据类型
var a int 这就是声明了一个变量,变量名是a
var num1 float32 这也声明了一个变量,表示一个单精度类型的小数,变量名是num1
初始化变量
在声明变量的时候,就给值
var a int =45 这就是初始化变量a
使用细节:如果声明时就给直接赋值,可以省略数据类型
var b = 400
给变量赋值
比如你先给声明了变量:var num int //默认0
然后,再给值 num =780,这就是给变量赋值
3.6程序中 + 号的使用
1.当左右两边都是数值型时,则作加法运算
2.当左右都是字符串,则做字符串拼接
3.7数据类型的基本介绍
3.8整数类型
3.8.1基本介绍
3.8.2整数的各个类型
3.8.3整数的使用细节
1.Golang 各整数类型分:有符号和无符号,int uint 的大小和系统有关。
2.Golang的整形默认声明为init型
package main
import (
"fmt"
"unsafe"
)
// func main1() {
// var i int = 1
// fmt.Println("i=", i)
// var j int16 = 128 //当大于128 init16就会报错
// fmt.Println("j =", j)
// }
// 整型的类型
func main() {
// var a int = 89000
// fmt.Println("a=", a)
// var b uint = 1
// var c byte = 255
// fmt.Println("b=", b, "c=", c)
// 整型的使用细节
var n1 = 100 //
fmt.Printf("n1 的类型 %T \n", n1)
var n2 int64 = 100
fmt.Printf("n2 的类型 %T n2占用的字节数是%d", n2, unsafe.Sizeof(n2))
var age byte = 90
fmt.Printf("\nage的类型 %T,age占用的字符串是%d", age, unsafe.Sizeof(age))
}
3.9 小数类型/浮点数
3.9.1基本介绍
小数类型就是用于存放小数的,比如1.2.0.23-1.911
3.9.2案例展示
package main
import (
"fmt"
"unsafe"
)
func main() {
var price float32 = 89.12
fmt.Println("price=", price)
fmt.Printf("\nprice 的数据类型是 %T, price的数据大小是 %d", price, unsafe.Sizeof(price))
}
执行结果:
3.9.3小数类型分类
1.关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
说明:浮点数都是有符号的.
func main() {
var price float32 = 89.12
fmt.Println("price=", price)
fmt.Printf("\nprice 的数据类型是 %T, price的数据大小是 %d", price, unsafe.Sizeof(price))
var num1 float32 = -0.00089
var num2 float64 = -7809656.09
fmt.Println("\nnum1 = ", num1, "\nnum2 = ", num2)
}
执行结果
- 尾数部分可能会丢失,造成精确度损失.
func main() {
var num3 float32 = -123.00000901
var num4 float64 = -123.00000901
fmt.Println("num3=", num3, "\nnum4=", num4)
}
执行结果
说明:float64 的精度比 float32 的要准确.
说明:如果我们要保存一个精度高的数,则应该选用 float64
3.浮点型的存储分为三部分:符号位+指数位+尾数位 在存储过程中,精度会有丢失
3.9.4 浮点型的使用细节
1.Golang 浮点类型有固定的范围和字段成都,不受具体OS的影响
2.Golang 的浮点型默认声明为float64类型
func main() {
var num5 = 1.1
fmt.Printf("num5的数据类型是%T \nnum5占用大小为:%d", num5, unsafe.Sizeof(num5))
}
3.浮点型常量有两种表示形式
十进制数形式: 如:5.12 .512=0.512 必须有小数点
科学计数法形式:如:5.123e2 =5.12* 10 的2次方 5.12E-2 = 5.12/10 的2次方
func main() {
//十进制数形式
var num6 = 5.12
num7 := .123 //=>0.123 省略了“var”
fmt.Println("num6=", num6, "num7=", num7)
//科学计数法形式
num8 := 5.1234e2
num9 := 5.1234e2
num10 := 5.1234e-2
fmt.Println(num8, num9, num10)
}
- 通常情况下,使用float64 ,因为它比float32 更精确
3.10 字符类型
3.10.1 基本介绍
Golang 中没有专门的字符类型,如果要存储单个字符(字母),一般使用 byte 来保存。
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。也
就是说对于传统的字符串是由字符组成的,而 Go 的字符串不同,它是由字节组成的。
3.10.2 案例
package main
import "fmt"
func main() {
var c1 byte = 'a'
var c2 byte = '0'
//当直接输出byte的值,会输出了对于的字符的码值
fmt.Println("直接输出:c1=", c1, "直接输出:c2=", c2)
//输出对应的字符串,需要使用格式化输出
fmt.Printf("格式化输出:c1=%c 格式化输出:c2=%c\n", c1, c2)
}
对上面的代码说明
1.如果保存的字符串在ASCII表的,比如{0-1,a-z,A-Z}直接可以保存到byte
2.如果我们保存的字符对于码值大于255,这时我们可以考虑使用int类型保存
3.如果我们需要安装字符的方式输出,这时我们需要格式化输出,即
fmt.Printf("%c",c1)..
3.10.3 字符类型使用细节
- 字符常量是用单引号(‘’)括起来的单个字符。例如:var c1
byte = ‘a’
var c2 int = ‘中’
var
c3
byte =
‘9’
2) Go 中允许使用转义字符 '\’来将其后的字符转变为特殊字符型常量。例如:var c3 char
= ‘\n’
// '\n’表示换行符
3) Go 语 言 的 字 符 使 用 UTF-8 编 码
, 如 果 想 查 询 字 符 对 应 的 utf8 码 值
http://www.mytju.com/classcode/tools/encode_utf8.asp
英文字母-1 个字节
汉字-3 个字节
4) 在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
5) 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的 unicode 字符
func main() {
var c4 = 22269
fmt.Printf("格式化输出c4= %c \n", c4) // '\n' 是换行符号
fmt.Println("直接输出c4=", c4)
}
执行结果:
- 字符类型是可以进行运算的,相当于一个整数,因为它都对应有 Unicode 码.
func main() {
var n1 = 10 + 'a' //10 + 97=107
fmt.Println("n1=", n1)
}
3.10.4 字符串类型本质探讨
1.字符型 储存到 计算机中,需要将字符串对于的码值(整数)找出来
储存: 字符—>对应码值表---->二级制------>存储
读取: 二级制---->码值---->字符---->读取
2.字符和码值的队友关系是通过字符编码表决定的
3.go语言的编码都统一成了utf-8。非常的方便,很统一,再也没有编码乱码的困扰了
3.11 布尔类型
3.11.1 基本介绍
1.布尔类型也叫bool类型,bool类型数据只允许取值true 和false
2.bool类型占1个字节
3.bool类型适于逻辑运算,一般用于程序流程控制
if条件控制语句
for循环控制语句
3.11.2 案例演示
package main
import (
"fmt"
"unsafe"
)
func main() {
var b = false
fmt.Println("b = ", b)
//1.bool 类型占用的储存空间是1个字节
fmt.Println("b 的占用空间=", unsafe.Sizeof(b))
//2.bool类型只能取true或者false
}
执行结果:
3.12 String类型
3.12.1基本介绍
字符串就是一串固定长度的字符串连接节气的字符序列。Go的字符串是由单个字节链接起来的。Go语言的字符串的字节码使用UTF-8编码标识Unicode文本
3.12.2案例展示
//演示
package main
import "fmt"
//go语言中Sting类型使用
func main() {
var address string = "北京长城 110 hello world"
fmt.Printf(address)
}
执行结果:
3.12.3 Sting 使用注意事项和细节
- go语言的字符串使用UTF-8编码标识Unicode文本,这样Golang统一使用UTF-8编码,不会再出现中文乱码问题
- 字符串一旦赋值了,字符串就不能修改了:再Go中字符串是不可变的
3.字符串的两种表示形式
- 双引号,会识别转义字符
- 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击,输出源代码等效果
func main() {
//使用的反引号
str2 := "abc\nabc"
fmt.Println(str2)
//使用单引号
str3 := `abc \n abc
qqqq
dd w2`
fmt.Println(str3)
}
执行结果:
4.字符串拼接
//4.字符串拼接
func main() {
var str = "hello" + " " + "world"
fmt.Println(str)
}
5.多行字符串
//5.当一行字符串太长的时候,需要用到段工行字符串,可以如下处理
funcmain() {
str:="hello"+" Zhangsan,"+"我是"+
"daming"
fmt.Println(str)
}
执行结果:
3.13 基本数据类型的默认值
3.13.1基本介绍
再go中,数据类型都有一个默认值,当程序员没有赋值时,就会暴露默认值,再go中,默认值又叫做零值
3.13.2基本数据类型的默认值如下
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0 |
字符串 | “” |
布尔类型 | false |
package main
import "fmt"
func main() {
var a int
var b float32
var c float64
var isMarried bool
var name string
fmt.Printf("a = %d, b = %v, c = %v ,isMarried = %v ,name = %v", a, b, c, isMarried, name)
}
执行结果:
3.14 基本数据类型的相互转换
3.14.1 基本介绍
Golang和java /c 不同, Go在不同类型的变量直接赋值时需要显示转换。也就是Golang中数据类型不能自动转换
3.14.2 基本语法
表达式T(v)将值v 转换为类型T
T:就是数据类型,比如init32,init64,float32 等等
v:就是需要转换的变量
3.14.3 案例展示
package main
import "fmt"
//数据类型转换
func main() {
var i int32 = 100
//希望将i => float
var n1 float32 = float32(i)
var n2 int8 = int8(i)
var n3 int64 = int64(i)
fmt.Printf("i = %v n1 =%v n2 =%v n3=%v", i, n1, n2, n3)
}
执行结果:
3.14.4基本数据类型相互转换的注意事项
1.Go中,数据类型的转换可以是从表示范围小–>表示范围大,也可以、范围大–>范围小
2.被转化的是变量存储的数据(即值),变量本身的数据类型并没有变化
3.在转换中,比如int64 转成int8 【-128-127】,编译不hi报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。因此在转换时,需要考虑范围
func main() {
var num1 int64 = 999999
var num2 int8 = int8(num1)
fmt.Println("num2=", num2)
}
转换结果:
3.14.5 联系
package main
import "fmt"
func main1() {
var n1 int32 = 12
var n2 int64
var n3 int8
//若实现需要进行数据转换操作,否则报错
n2 = int64(n1) + 20
n3 = int8(n1) + 20
fmt.Println("n2 =", n2, "n3=", n3)
}
func main() {
var n1 int32 = 12
//var n3 int8
var n4 int8
n4 = int8(n1) + 127
//n3 = int8(n1) + 128 //编译失败
fmt.Println(n4)
}
3.15 基本数据类型和String的转换
3.15.1基本介绍
在程序开发中,我们经常将基本数据类型转成String 或者将String 转成基本数据类型
3.15.2 基本类型转Sting
方式一:fmt.Sprint(“%参数”,表达式)
函数介绍
参数需要和表达式的数据类型相匹配
fmt.Spintf()…会返回转换后的字符串
package main
import "fmt"
func main() {
// 基本数据类型转成String使用
var num1 int = 99
var num2 float64 = 23.456
var b bool = true
var myCher byte = 'h'
var str string //空的
str = fmt.Sprintf("%d", num1)
fmt.Printf("str type %T str = %q\n", str, str)
str = fmt.Sprintf("%f", num2)
fmt.Printf("str type %T str = %q\n", str, str)
str = fmt.Sprintf("%t", b) fmt.Printf("str tyep %T str=%q\n", str, str)
str = fmt.Sprintf("%c", myCher)
fmt.Printf("str type %T str= %q\n", str, str)
}
执行结果
方式二: 使用strconv包函数
func main() {
//第二种方式 strconv函数
var num3 int = 99
var num4 float64 = 23.456
var b2 bool
var str string
str = strconv.FormatInt(int64(num3), 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))
fmt.Printf("str type %T str = %q\n", str, str)
}
运行结果
3.15.3 string类型转基本数据类型
使用时strconv包函数
func main() {
var str string = "true"
var b bool
//b, _=strconv.PareBool(str)
//说明
//1.strconv.ParseBool(str) 函数会返回两个值,(varlue bool,err error)
//2.因为我只想获取到varlue bool,不想获取err 所以我使用_忽略
b, _ = strconv.ParseBool(str)
fmt.Printf("b type %T b = %v\n", b, b)
var str2 string = "1234590"
var n1 int64
var n2 int
n1, _ = strconv.ParseInt(str2, 10, 64)
n2 = int(n1)
fmt.Printf("n1 type %T n1 = %v\n", n1, n1)
fmt.Printf("n2 type %T n2 = %v\n", n2, n2)
var str3 string = "123,456"
var f1 float64
f1, _ = strconv.ParseFloat(str3, 64)
fmt.Printf("f1 type %T f1=%v\n", f1, f1)
}
运行结果
3.15.4 string 转基本数据类型的注意事项
在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据,比如我们可以把“123”转成整数,但是不能把“hello”转成一个整数,如果这样做,Golang直接将其转成0,其他类型也是一样的,float=>0 ,bool=>false
func main() {
//在将String类型转成基本数据类型时,要确保String类型能够转成有效的数据,比如我们可以把“123”转成整数,但是不能把“hello”
//转成一个整数,如果这样做,Golang直接将其转成0,其他类型也是一样的,float=>0 ,bool=>false
var str string = "hello"
var n3 int64 = 11
n3, _ = strconv.ParseInt(str, 10, 64)
fmt.Printf("n3 type %T n3 =%v\n", n3, n3)
}
执行结果
3.16 指针
3.16.1 指针介绍
1.基本数据类型,变量存的就是值,也叫值类型
2.获取表里的地址,由&,比如:var num int,获取num的地址:&num
基本数据类型在内存的布局
package main
import "fmt"
func main() {
//基本数据类型在内存布局
var i int = 10
//i 的地址是什么
fmt.Println("i的内存地址是=", &i)
}
执行结果
3.指针类型,指针变量村的是一个地址,这个地址指向的空间存的才是值
比如:var ptr * int = &num
举例说明:指针在内存的布局
func main() {
//基本数据类型在内存布局
var i int = 10
//i 的地址是什么
fmt.Println("i的内存地址是=", &i)
//下面的var ptr * int = &i
//1.ptr 是一个指针变量
//2.ptr 的类型是 "*int"
//3.ptr本身的值 &i
var ptr *int = &i
fmt.Printf("ptr指针存的地址 = %v\n", ptr)
}
执行结果:
4.获取指针类型所指向的值,使用: *,比如:var ptr int,使用ptr获取ptr指向的值
package main
import "fmt"
func main() {
//基本数据类型在内存布局
var i int = 10
//i 的地址是什么
fmt.Println("i的内存地址是=", &i)
//下面的var ptr * int = &i
//1.ptr 是一个指针变量
//2.ptr 的类型是 "*int"
//3.ptr本身的值&i
var ptr *int = &i
fmt.Printf("ptr指针存的地址 = %v\n", ptr)
fmt.Printf("ptr 的地址=%v\n", &ptr)
fmt.Printf("ptr指向的值=%v", *ptr)
}
执行结果
3.16.2 案例展示
package main
import "fmt"
func main() {
//1.获取int变量num的地址,并显示到终端
var num int = 9
fmt.Printf("num在内存中的地址=%v\n", &num)
//2.将num的地址赋值给指针ptr,并通过ptr去修改num的值
var ptr *int //指针类型
ptr = &num //ptr 指针指向的内存空间等于&num
*ptr = 10 //*ptr 获取指针类型所指向的值,相当于&num所存储的值,这里的将其值设置为10。
fmt.Printf("%v\n", num)
fmt.Printf("%v", &ptr)
}
执行结果
3.16.3 练习题
package main
import "fmt"
func main1() {
//1.获取int变量num的地址,并显示到终端
var num int = 9
fmt.Printf("num在内存中的地址=%v\n", &num)
//2.将num的地址赋值给指针ptr,并通过ptr去修改num的值
var ptr *int //指针类型
ptr = &num //ptr 指针指向的内存空间等于&num
*ptr = 10 //*ptr 获取指针类型所指向的值,相当于&num所存储的值,这里的将其值设置为10。
fmt.Printf("%v\n", num)
fmt.Printf("%v", &ptr)
}
func main2() {
var a int = 300
//var ptr *int = a //错误,ptr类型为指针类型,不能直接等于值 &a
var ptr *int = &a
fmt.Printf("ptr的值=%v", *ptr)
}
func main3() {
var a int = 300
//var ptr *float32 = &a //错误原因,a的类型为int,ptr指针类型为float32,所以错误,先将a的类型转换成float32的
var a1 float32 = float32(a)
var ptr *float32 = &a1
fmt.Printf("ptr的值=%v", *ptr)
}
func main() {
var a int = 300
var b int = 400
var ptr *int = &a
*ptr = 100
ptr = &b
*ptr = 200
fmt.Printf("a =%d,b = %d ,*ptr=%d:", a, b, *ptr) //a=100,b=200,*ptr = 200
}
3.16.4指针的使用细节
1.值类型,都有对应的指针类型,形式为 *数据类型(如:*int、*float32……)
2.值类型包括:基本数据类型 int 系列,float系列,bool,string、数组和结构体 struct
3.17值类型和引用类型
3.17.1值类型和引用类型的说明
1.值类型:基本数据类型 int系列、float系列,bool、String、数据和结构题struct
2.引用类型:指针、slice切片、map、管道、interface等都是引用类型
3.17.2 值类型和引用类型使用特点
1.值类型: 变量直接存储值,内存通常在栈中分配
示意图:
2.引用类型:变量储存的是一个地址,这个地址对于的空间才是真正储存数据(值),内存通常在堆上分配。当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收
示意图:
3.内存的栈区和堆区示意图
3.18 标识符的命名规范
3.18.1 标识符概念
1.Golang对各种变量、方法、函数等命名时使用的字符串序列称为标识符
2.凡是自己可以起名字的地方都叫标识符
3.18.2标识符的命名规则
1.由26个英文字符大小写,0-9,"“组成
2.数字不可以开头
3.Golang中严格区分大小写
4.表示符不能包含空格
5.下划线”"本身在GO中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但是它对于的值会被忽略,所以仅能被作为占位符使用,不能作为表示夫使用
6.不能以系统保留关键字作为标识符,共25个,比如break、if等等
3.18.3标识符的案例
hello//ok
hello12//ok
1hello//error,不能以数字开头
h-b//error,不能使用-
x h//error,不能含有空格
h_4//ok
_ab//ok
int//ok,我们要求大家不要这样使用
float32//ok,我们要求大家不要这样使用
_//error
Abc//ok
3.18.4 标识符命名注意事项
1.包名:保持Package的名字和目录保持一致,进行了采用油意义的包名,简短,有意义,不要和标准库有冲出
2.变量名、函数名、常用名:采用驼峰法
3.如果变量名、函数名、常用名首字母大写,则可以被其他包访问;如果字母小写,则只能在本包中使用
(注:可以简单的理解成,首字母大写是公开的,首字母小写是私有的),在golang没有public,private等关键字。)
注意,在导入自定义包的时候,包的路径的组成为 :
- 系统环境变量中的 $GOPATH变量对应的值
- 自己要导入包的路径
import "xxx/xx/x"
$GOPATH + 'src/' + 'xxx/xx/x'
案例演示:
go 命令现在默认在模块感知模式下构建包,即使没有 go.mod 存在也是如此。
“您可以将 GO111MODULE 设置为 auto,仅当当前目录或任何父目录中存在 go.mod 文件时,才能启用模块感知模式。
在命令提示符下
go env -w GO111MODULE=auto
3.19 系统保留关键字
在go中,为了简化代码编译过程中对代码的解析,其定义的保留关键字只有25个
break | default | func | interface | select |
---|---|---|---|---|
case | defer | go | map | struct |
chan | else | goto | package | switch |
const | fallthrough | if | range | type |
continue | for | import | return | var |
3.20 系统的预定义标识符
除了保留关键字除外,Go还提供了36个预定义的标识符,其中包括基础类型和系统内嵌函数
append | bool | byte | cap | close | complex |
---|---|---|---|---|---|
complex64 | complex128 | uint16 | copy | false | float32 |
float64 | imag | int | int8 | int16 | uint32 |
int32 | int64 | iota | len | make | new |
nil | panic | uint64 | println | real | |
recover | string | true | uint | uint8 | uintprt |