golang语言的模块化调用、go语言中程序的通道| 青训营笔记

115 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。

模块化调用

在第一次作业的第三题中遇到了这样一个需求:并行调用两个翻译引擎进行翻译。可我的两个翻译引擎在两个不同的go文件里,如何在go语言中调用另一个go文件的函数? 要解决这个问题,首先要了解go语言中对于函数或字段的可见性规则,也就是访问权限。

在Java中,我们可以通过private、public、protected关键字来规定字段或函数的权限,但是在go语言中有更加简洁的方法:如果以大写字母开头表示能被其他包调用或访问,非大写开头就只能在包内使用。

如:

func Query() {
   ...
} //函数首字母为大写,可以被包外调用
type DictRequest struct {
   TransType string `json:"trans_type"` //结构体的字段名首字母均为大写,可以被包外调用
   Source    string `json:"source"`
   UserID    string `json:"user_id"`
}
func query() {
   ...
} //函数首字母为小写,不可以被包外调用


我们只能调用公开的字段或函数,通过包名.模块名调用

demo.Query() //调用demo包下的Query函数

go语言中程序的通道

go语言中实现程序并发执行的方式有通道(channel)、互斥锁和等待组。

通道(channel)

Go语言的并发模型是CSP(Communicating Sequential Processes),提倡通过通信共享内存而不是通过共享内存而实现通信。

channel操作

发送:

ch <- 10 // 把10发送到ch中

接收:

x := <- ch // 从ch中接收值并赋值给变量x
<-ch       // 从ch中接收值,忽略结果

关闭:

close(ch)

无缓冲的通道 (阻塞通道)

无缓冲的通道只有在有人接收值的时候才能发送值

func main() {
    ch := make(chan int)
    ch <- 10
    fmt.Println("发送成功")
}

该代码由于没有人接受该通道中的产物,故不能发送到ch中

解决办法:启用一个goroutine去接收值

func recv(c chan int) {
    ret := <-c
    fmt.Println("接收成功", ret)
}
func main() {
    ch := make(chan int)
    go recv(ch) // 启用goroutine从通道接收值
    ch <- 10
    fmt.Println("发送成功")
}

有缓冲的通道

我们可以在使用make函数初始化通道的时候为其指定通道的容量,同样可以解决上面的问题

func main() {
    ch := make(chan int, 1) // 创建一个容量为1的有缓冲区通道
    ch <- 10
    fmt.Println("发送成功")
}