今天找到了几个优秀的Go学习资源:
Go 语言优秀资源整理,为项目落地加速 https://shockerli.net/post/go-awesome/;
Go 学习之路:Go 开发者博客、Go 微信公众号、Go 学习资料(文档、书籍、视频) https://github.com/talkgo/read star:4.1k
Go by Example是对 Go 基于实践的介绍,包含一系列带有注释说明的示例程序,Go 是一门被设计用来构建简单、高效、可信赖软件的开源程序设计语言;三方的日志库,如logrus、zap;
今天主要对结构体、方法、接口、异步的应用进行了加强,写了些测试代码,看了些开源的代码框架,但对有些语法看起来比较陌生,总体也就是能看得懂,离随心所欲的写逻辑还是欠一些;和之前写过Go业务系统的同事聊,对比C/C++,他也是觉得业务做起来很快,对Go实现高效、快速开发业务系统的判断更有信心了。
结构体、方法的操作细节:
//Saiyan 结构体
type Saiyan struct {
Name string
Power int
}
func testStructFunc() {
var tempSaiyan = Saiyan{
Name: "test",
Power: 90900,
}
fmt.Printf("tempSaiyan:")
fmt.Println(tempSaiyan.Name, ",", tempSaiyan.Power)
addStructTest(&tempSaiyan)
fmt.Println(tempSaiyan.Name, ",", tempSaiyan.Power)
tempSaiyan.testAddStructTest()
fmt.Println(tempSaiyan.Name, ",", tempSaiyan.Power)
var tempSaiyan2 Saiyan = Saiyan{}
tempSaiyan2.Name = "test2"
tempSaiyan2.Power = 3000
fmt.Printf("tempSaiyan2:")
fmt.Println(tempSaiyan2.Name, ",", tempSaiyan2.Power)
//使用构造方法进行构造对象
var tempSaiyan3 = NewSaiyan("hello", 30000)
fmt.Printf("tempSaiyan3:")
fmt.Println(tempSaiyan3.Name, ",", tempSaiyan3.Power)
//使用new进行构造对象
var tempSaiyan4 = new(Saiyan)
tempSaiyan4.Name = "test4"
tempSaiyan4.Power = 30012
fmt.Printf("tempSaiyan4:")
fmt.Println(tempSaiyan4.Name, ",", tempSaiyan4.Power)
//使用new等效的方法进行初始化
var tempSaiyan5 = &Saiyan{
Name: "goku",
Power: 90000,
}
fmt.Printf("tempSaiyan5:")
fmt.Println(tempSaiyan5.Name, ",", tempSaiyan5.Power)
}
//通过指针修改属性的值
func addStructTest(s *Saiyan) {
s.Power += 10000
}
//作用在对象上的方法
func (s *Saiyan) testAddStructTest() {
s.Power += 10000
}
//NewSaiyan 给结构体增加构造函数
func NewSaiyan(name string, power int) *Saiyan {
return &Saiyan{
Name: name,
Power: power,
}
}
channel、单向通道
func channelTest() {
//channel,初始化队列是10
var globalCh1 chan int = make(chan int, 10)
go channelSend(globalCh1)
go channelRecv(globalCh1)
}
func channelSend(channel chan int) {
//只写单向通道
// func channelSend(channel chan<- int) {
//ch <- 10 // 把10发送到ch中
fmt.Printf("channelSend x:%d\n", 10)
channel <- 10
go delayTestCloseFunc(channel)
}
//CLOSEFLAG 关闭flag
const CLOSEFLAG int = 4
func delayTestCloseFunc(channel chan int) {
flag := <-channel
if flag == CLOSEFLAG {
fmt.Printf("delayTestCloseFunc close channel\n")
//关闭通道
close(channel)
}
}
func channelRecv(channel chan int) {
//只读单向通道
// func channelRecv(channel <- chan int) {
//x := <- ch // 从ch中接收值并赋值给变量x
x := <-channel
fmt.Printf("channelRecv x:%d\n", x)
//发送结束标志
channel <- CLOSEFLAG
}
接口补充
//Driver 接口声明
type Driver interface {
ReadData() string
WriteData(string)
}
// UsbDriver usb驱动显示的实现了接口
type UsbDriver struct {
data string
Driver
}
//ReadData usb获取数据
func (d *UsbDriver) ReadData() string {
return "usb中的数据: " + d.data
}
//WriteData usb写入数据
func (d *UsbDriver) WriteData(data string) {
d.data = data
}
//FileDriver 文件驱动隐式的实现了接口
type FileDriver struct {
data string
}
//ReadData 文件获取数据
func (d *FileDriver) ReadData() string {
return "文件中的数据: " + d.data
}
//WriteData 文件写入数据
func (d *FileDriver) WriteData(data string) {
d.data = data
}
func testInterface() {
driver := &FileDriver{}
PrintDriverData(driver, "18岁的静静")
}
//PrintDriverData 打印驱动数据
func PrintDriverData(driver Driver, data string) {
driver.WriteData(data)
fmt.Println(driver.ReadData())
}
小技巧
1、_下划线在代码中的作用比较好理解,就是占位符,通常忽略返回值,不关心返回值具体是多少;
比如os.Open,返回值为*os.File,error, 普通写法是:
f,err := os.Open("xxxxxxx")
如果此时不需要知道返回的错误值,就可以用如下忽略了error变量的返回值:
f, _ := os.Open("xxxxxx")
2、import 导入包时,包名前面的_的作用:
import (
_ "gfast/boot"
_ "gfast/router"
"github.com/gogf/gf/frame/g"
)
在Golang里,import的作用是导入其他package,import 下划线(如:import _ hello/imp)的作用:当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。这个时候就可以使用 import _ 引用该包。即使用【import _ 包路径】只是引用该包,仅仅是为了调用init()函数,所以无法通过包名来调用包中的其他函数。
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
第二个import就是不直接使用mysql包,只是执行一下这个包的init函数,把mysql的驱动注册到sql包里,然后程序里就可以使用sql包来访问mysql数据库了。
组团学习网站:https://pub6.top 一起学习,一起牛!