今天找到了几个优秀的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, } }
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 一起学习,一起牛!
-------------------广告线---------------
项目、合作,欢迎勾搭,邮箱:promall@qq.com
本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com