主持人:欢迎Go同学
欢迎Go同学
Go同学:
大家好,我叫Go,一个开源的编程语言,能够让软件变得构造简单且高效。
1.记者:Go你好,请问你和其他语言同学有什么区别?
Go同学:
2.记者:Go你好,请问您可以用在哪些地方?
Go同学:
搭载 Web 服务器,存储集群或类似用途的巨型中央服务器。
3.记者:Go同学,听说您有强大的并发功能,可以给我们讲下吗?
Go同学:
只需要通过 go 关键字来开启 goroutine 即可。
goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的
goroutine 语法格式:
go 函数名( 参数列表 )
例如:
go f(x, y, z)
Go 允许使用 go 语句开启一个新的运行期线程, 即 goroutine,以一个不同的、新创建的 goroutine 来执行一个函数。同一个程序中的所有 goroutine 共享同一个地址空间。
package mainimport ( "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 hellotest hello hellotest test hello
4.记者:请问多线程之间如何传递数据?
Go同学:
通道(channel)是用来传递数据的一个数据结构
通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。
ch <- v // 把 v 发送到通道 ch v := <-ch // 从 ch 接收数据 // 并把值赋给 v
声明一个通道很简单,我们使用chan关键字即可,通道在使用前必须先创建:
ch := make (chan int )
注意 :默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端相应的接收数据。
以下实例通过两个 goroutine 来计算数字的平方-5,在 goroutine 完成计算后,它会计算两个结果的和:
package mainimport "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
通道缓冲区
通道可以设置缓冲区,通过 make 的第二个参数指定缓冲区大小:
ch := make(chan int, 100)
带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。
由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了。
注意 :如果通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。
package mainimport "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 遍历通道与关闭通道
Go 通过 range 关键字来实现遍历读取到的数据
package mainimport ( "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
5.记者:Go同学,请问怎么安装Go呢?
Go同学:
我支持的系统:Linux、FreeBSD、Mac OS、Windows。
安装包下载地址为:https://golang.org/dl/。
安装包下载
6.记者:Go同学,请问基础语法是怎么样的?
Go同学:
由多个标记组成,可以是关键字,标识符,常量,字符串,符号。
在 Go 程序中,一行代表一个语句结束,不需要分号。
标识符用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字。
7.记者:Go你好,数据类型的是怎么样的?
Go同学:
uint8、uint16、uint32**、 uint64 、 int8、int16、int32、int64、float32、float64、 complex64 、**complex128
8.记者:Go同学,请问您如何定义变量?
Go同学:
第一种,指定变量类型,如果没有初始化,则变量默认为零值 。
第三种,省略 var, 注意 *:=* 左侧如果没有声明新的变量,就产生编译错误
9.记者:Go同学,您如何定义常量?
Go同学:
const identifier [type] = value,略类型说明符 [type],因为编译器可以根据变量的值来推断其类型
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型
10.记者:Go同学,请问你有哪些运算符
Go同学:
11.记者:Go同学,您有哪些条件语句?
Go同学:if,if else,swith,select
12.记者:Go你好,循环有哪些需要注意的?
Go同学:我有for 循环,可以用break/continue/goto语句
13.记者:Go同学,请问如何定义函数
Go同学:
func function_name ( [parameter list] ) [return_types ] { 函数体 }
函数定义解析:
function_name:函数名称,函数名和参数列表一起构成了函数签名。
parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
14.记者:Go语言有哪些变量作用域
Go同学:
15.记者: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
16.记者:Go同学,请问如何处理异常?
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" ) } // 实现 }
17.记者:Go同学,有什么好用的开发工具吗?
Go同学:
IntelliJ idea是非常强大的一款IDE,支持丰富的插件。需要安装两个插件Go和File Watcher
GoLand 是 Jetbrains 家族的 Go 语言 IDE,有 30 天的免费试用期。
LiteIDE 是一款开源、跨平台的轻量级 Go 语言集成开发环境(IDE)
参考资料:
https://www.runoob.com/go/go-tutorial.html
关于我
悟空 爱学习的程序猿,自主开发了Java学习平台、PMP刷题小程序。目前主修Java、多线程、SpringBoot、SpringCloud、k8s。本公众号不限于分享技术,也会分享工具的使用、人生感悟、读书总结。