❝我是悟空 爱学习的程序猿,自主开发了Java学习平台、PMP刷题小程序。目前主修Java、多线程、SpringBoot、SpringCloud、k8s。本公众号不限于分享技术,也会分享工具的使用、人生感悟、读书总结。
本篇来讲下Go的基本使用,欢迎点赞/转发/在看!
欢迎Go同学
Go同学:
大家好,我叫Go,一个开源的编程语言,能够让软件变得构造简单且高效。
Go同学:
Go同学:
Go同学:
只需要通过 go 关键字来开启 goroutine 即可。
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的
goroutine 语法格式:
go 函数名( 参数列表 )
例如:
go f(x, y, z)
Go 允许使用 go 语句开启一个新的运行期线程, 即 goroutine,以一个不同的、新创建的 goroutine 来执行一个函数。同一个程序中的所有 goroutine 共享同一个地址空间。
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("test")
say("hello")
}
执行以上代码,输出的 hello 和 world 是没有固定先后顺序。因为它们是两个 goroutine 在执行:
test
test
hello
hello
test
hello
hello
test
test
hello
Go同学:
通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <-
用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。
ch <- v // 把 v 发送到通道 ch
v := <-ch // 从 ch 接收数据
// 并把值赋给 v
声明一个通道很简单,我们使用chan关键字即可,通道在使用前必须先创建:
ch := make(chan int)
注意:默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端相应的接收数据。
以下实例通过两个 goroutine 来计算数字的平方-5,在 goroutine 完成计算后,它会计算两个结果的和:
package main
import "fmt"
func square(s int, c chan int) {
result := s * s - 5
c <- result // 把 result 发送到通道 c
}
func main() {
c := make(chan int)
go square(3, c)
go square(4, c)
x, y := <-c, <-c // 从通道 c 中接收
fmt.Println(x, y, x+y)
}
输出结果为:
4 11 15
ch := make(chan int, 100)
注意:如果通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。
package main
import "fmt"
func main() {
// 这里我们定义了一个可以存储整数类型的带缓冲通道
// 缓冲区大小为3
ch := make(chan int, 3)
// 因为 ch 是带缓冲的通道,我们可以同时发送3个数据
// 而不用立刻需要去同步读取数据
ch <- 100
ch <- 200
ch <- 300
// 获取这两个数据
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
}
输出结果
100
200
300
Go 通过 range 关键字来实现遍历读取到的数据
package main
import (
"fmt"
)
func square(n int, c chan int) {
for i := 1; i <= n; i++ {
x := i * i
c <- x
}
close(c)
}
func main() {
c := make(chan int, 5)
go square(5, c)
// range 函数遍历每个从通道接收到的数据,因为 c 在发送完 5 个
// 数据之后就关闭了通道,所以这里我们 range 函数在接收到 5 个数据
// 之后就结束了。如果上面的 c 通道不关闭,那么 range 函数会报死锁的错误提示。
for i := range c {
fmt.Println(i)
}
}
输出结果:
1
4
9
16
25
通道不关闭,造成死锁的错误提示:
1
4
9
16
25
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/box/main.go:23 +0xf1
Exited with error status 2
Go同学:
安装包下载
Go同学:
Go同学:
Go同学:
Go同学:
Go同学:
Go同学:if,if else,swith,select
Go同学:我有for 循环,可以用break/continue/goto语句
Go同学:
func function_name( [parameter list] ) [return_types] {
函数体
}
函数定义解析:
Go同学:
Go同学:
Go 语言数组声明需要指定元素类型及元素个数,语法格式如下:
var variable_name [SIZE] variable_type
Go语言初始化数组:
var test = [5] float32{200.0, 2.0, 3.14, 20.0, 100.0}
可以通过索引获取/设置数组中的值:
test[4]
test[2] = 100
Go同学:
Go 语言通过内置的错误接口提供了非常简单的错误处理机制。
error类型是一个接口类型,这是它的定义:
type error interface {
Error() string
}
我们可以在编码中通过实现 error 接口类型来生成错误信息。
函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// 实现
}
Go同学:
IntelliJ idea是非常强大的一款IDE,支持丰富的插件。需要安装两个插件Go和File Watcher
GoLand 是 Jetbrains 家族的 Go 语言 IDE,有 30 天的免费试用期。
LiteIDE 是一款开源、跨平台的轻量级 Go 语言集成开发环境(IDE)
悟空
爱学习的程序猿,自主开发了Java学习平台、PMP刷题小程序。目前主修Java、多线程、SpringBoot、SpringCloud、k8s。本公众号不限于分享技术,也会分享工具的使用、人生感悟、读书总结。