Go语言学习(三)

2023-05-02 15:22:41 浏览数 (1)

今天找到了几个优秀的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实现高效、快速开发业务系统的判断更有信心了。

结构体、方法的操作细节:

代码语言:javascript复制
//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、单向通道

代码语言:javascript复制
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:%dn", 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 channeln")
        //关闭通道
        close(channel)
    }
}

func channelRecv(channel chan int) {
    //只读单向通道
    // func channelRecv(channel <- chan int) {
    //x := <- ch // 从ch中接收值并赋值给变量x
    x := <-channel
    fmt.Printf("channelRecv x:%dn", x)

    //发送结束标志
    channel <- CLOSEFLAG
}

接口补充

代码语言:javascript复制
//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, 普通写法是:

代码语言:javascript复制
f,err := os.Open("xxxxxxx")

如果此时不需要知道返回的错误值,就可以用如下忽略了error变量的返回值:

代码语言:javascript复制
f, _ := os.Open("xxxxxx")

2、import 导入包时,包名前面的_的作用:

代码语言:javascript复制
import (
    _ "gfast/boot"
    _ "gfast/router"
    "github.com/gogf/gf/frame/g"
)

在Golang里,import的作用是导入其他package,import 下划线(如:import _ hello/imp)的作用:当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。这个时候就可以使用 import _ 引用该包。即使用【import _ 包路径】只是引用该包,仅仅是为了调用init()函数,所以无法通过包名来调用包中的其他函数。

代码语言:javascript复制
import "database/sql"
import _ "github.com/go-sql-driver/mysql"

第二个import就是不直接使用mysql包,只是执行一下这个包的init函数,把mysql的驱动注册到sql包里,然后程序里就可以使用sql包来访问mysql数据库了。


组团学习网站:https://pub6.top 一起学习,一起牛!

0 人点赞