golang标准库io包
Go语言中,为了方便开发者使用,将IO操作封装在了如下几个包中:
io为IO原语(I/O primitives)提供基本的接口
io/ioutil封装一些实用的I/O函数
fmt实现格式化I/O,类似C语言中的printf和scanf
bufio实现带缓冲I/O
1. 基本的IO接口
在io包中最重要的两个接口:Reader和Writer接口,所提到的各种IO包,都跟这两个接口有关,也就说,只要实现了这两个接口,他就有了IO的功能
1.1 Reader接口
123type Reader interface { Read(p []byte) (n int, err error)}
1.2 Writer接口
123type Writer interface { Write(p []byte) (n int, err error)}
1.3 哪些类型实现了Reader和Writer接口
123456789os.File 同时实现了io.Reader和io.Writerstrings.Reader 实现了io.Readerbufio.Re ...
golang标准库os模块
os标准库实现了平台(操作系统)相关的编程接口
1. 文件目录相关
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140package mainimport ( "fmt" "log" "os")// 创建文件func createFile() { if f, err := os.Create("test.txt"); err != n ...
golang并发编程
1. 协程
Golang中的并发是函数相互独立运行的能力。Goroutines是并发运行的函数。Golang提供了Goroutines作为并发处理操作的一种方式。
创建一个携程非常简单,就是在一个任务函数前面添加一个go关键字
1. 实例
12345678910111213141516171819202122232425package mainimport ( "fmt" "sync" "time")var wg sync.WaitGroupfunc show(msg string) { defer wg.Done() for i := 0; i < 5; i++ { fmt.Printf("msg: %v\n", msg) time.Sleep(time.Millisecond * 100) }}func main() { wg.Add(1) go show("java") wg.Wait() fmt.Println(&quo ...
golang面向对象
面向对象的概念
洗衣服过程剖析:
给洗衣机里加脏衣服和洗衣粉。
启动洗衣机。
洗衣机自动注水,然后滚动。
脏衣服从黑颜色变成白颜色。
洗衣机自动停止。
用面向过程的思想实现代码。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859//准备洗衣服//输入参数://powder 洗衣机里放多少洗衣粉//closes 洗衣机里放多少衣服//clean 衣服是否是干净的//返回值://洗衣机是否开启//准备洗多少衣服func prepare(powder int, closes int, clean bool) (bool, int) { if powder <= 0 || closes <= 0 || clean == true { return false, 0 } return true, closes}//开始洗衣服//输入参数://washer_stat ...
golang包与工程化
用go mod管理工程
初始化项目:
1go mod init $module_name
$module_name和目录名可以不一样。上述命令会生成go.mod文件,该文件内容形如:
12345678module go-coursego 1.17require ( github.com/ethereum/go-ethereum v1.10.8 github.com/gin-gonic/gin v1.7.4)
Go依次从当前项目、GOROOT、GOPATH下寻找依赖包。
从当前go文件所在的目录逐级向上查找go.mod文件(假设go.mod位于目录mode_path下),里面定义了module_name,则引入包的路径为"module_name/包相对于mode_path的路径"。
go标准库提供的包在GOROOT/src下。
第三方依赖包在GOPATH/pkg/mod下。
从go1.7开始,go get只负责下载第三方依赖包,并把它加到go.mod文件里,由go install负责安装二进制文件。
go get github.com/m ...
golang接口
接口的基本概念
接口是一组行为规范的集合。
12345type Transporter interface { //定义接口。通常接口名以er结尾 //接口里面只定义方法,不定义变量 move(src string, dest string) (int, error) //方法名 (参数列表) 返回值列表 whistle(int) int //参数列表和返回值列表里的变量名可以省略}
只要结构体拥有接口里声明的所有方法,就称该结构体“实现了接口”。一个struct可以同时实现多个接口。
12345678910type Car struct { //定义结构体时无需要显式声明它要实现什么接口 price int}func (car Car) move(src string, dest string) (int, error) { return car.price, nil}func (car Car) whistle(n int) int { return n}
...
golang结构体
结构体创建、访问与修改
定义结构体
123456type user struct { id int score float32 enrollment time.Time name, addr string //多个字段类型相同时可以简写到一行里}
声明和初始化结构体
1234var u user //声明,会用相应类型的默认值初始化struct里的每一个字段u = user{} //用相应类型的默认值初始化struct里的每一个字段u = user{id: 3, name: "zcy"} //赋值初始化u = user{4, 100.0, time.Now(), "zcy", "beijing"} //赋值初始化,可以不写字段名,但需要跟结构体定义里的字段顺序一致
访问与修改结构体
12u.enrollment = time.Now() //给结构体的成员变量赋值fmt.Printf("id=%d, enrollm ...
golang指针
Go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量。传递数据使用指针,而无需拷贝数据。
类型指针不能进行偏移和运算
Go语言中的指针操作非常简单,只需要记住两个符号:&(取地址)和*(根据地址取值)
1. 指针地址和指针类型
每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用&字符放在变量前面对变量进行取地址操作。Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型。如*init、*init64、*string等。
2. 指针语法
一个指针变量指向了一个值的内存地址。(也就是我们声明了一个指针之后,可以像变量赋值一样,把一个值的内存地址放入到指针当中)
类似于变量和常量,在使用指针前你需要声明指针。
1var var_name *var-type
var-type:为指针类型
var_name:为指针变量名
*:用于指定变量是作为一个指针
3. 指针声明
12var ip *int // 指向整型var fp *float32 // 指 ...
golang函数
函数的基本形式
123456//函数定义。a,b是形参func argf(a int, b int) { a = a + b }var x, y int = 3, 6argf(x, y) //函数调用。x,y是实参
形参是函数内部的局部变量,实参的值会拷贝给形参。
函数定义时的第一个的大括号不能另起一行。
形参可以有0个或多个。
参数类型相同时可以只写一次,比如argf(a,b int)。
在函数内部修改形参的值,实参的值不受影响。
如果想通过函数修改实参,就需要指针类型。
123456func argf(a, b *int) { *a = *a + *b *b = 888}var x, y int = 3, 6argf(&x, &y)
slice、map、channel都是引用类型,它们作为函数参数时其实跟普通struct没什么区别,都是对struct内部的各个字段做一次拷贝传到函数内部。
123456789101112131415package mainimport "fmt"fun ...
golang流程控制
if
123if 5 > 9 { fmt.Println("5>9")}
如果逻辑表达式成立,就会执行{}里的内容。
逻辑表达式不需要加()。
"{"必须紧跟在逻辑表达式后面,不能另起一行。
123if c, d, e := 5, 9, 2; c < d && (c > e || c > 3) { //初始化多个局部变量。复杂的逻辑表达式 fmt.Println("fit")}
逻辑表达中可以含有变量或常量。
if句子中允许包含1个(仅1个)分号,在分号前初始化一些局部变量(即只在if块内可见)。
if-else的用法
12345678910color := "black"if color == "red" { //if只能有一个 fmt.Println("stop")} else if color == "green" ...