【go入门(二)】运算、函数和控制语句
文章目录
1.运算符
go语言和C语言所有运算符均一样,包括&
取地址符号和*
引用指针变量运算符号也一样。
2.条件分支控制(if-else,switch-case,select-case)
2.1if-else分支控制
go语言的if-else控制语句与C、java的使用方式相同,不过有一点需要注意:
if bool表达式{
//条件一执行的条件
}else if bool表达式{
//else if 条件下执行的语句
}else{
//else条件下执行的语句
}
else if 和else必须与上一个条件的}
位于同一行
2.2 switch-case分支控制
基本用法和C语言的switch用法大同小异。存在进阶用法
基本用法:
switch var{
case val1:
...
//break; ❌不用break也能跳出
case val2:
...
default:
...
}
进阶用法:
switch {
case condition1:
...
case condition2:
...
default:
` ...`
}
这样我感觉进阶版才叫做升级版的分支控制,像c语言的基础用法只能用一个变量的不同值来进行判断,书写一些多个变量来进行判断的条件将非常不友好
支持多汁判断:
switch var{
case val1,val2,val3:
...
case val4:
...
default:
...
}
2.3 select-case控制语句
在Go语言中,select
语句用于在多个通信操作中选择一个可用的操作执行。它通常与通道(channel)一起使用,以实现并发控制。select
语句允许你同时等待多个通道操作,以响应第一个准备好的通信,从而实现非阻塞的并发编程。
在通常情况下,select
语句会阻塞当前 Goroutine 并等待多个 Channel 中的一个达到可以收发的状态。但是如果 select
控制结构中包含 default
语句,那么这个 select
语句在执行时会遇到以下两种情况:
- 当存在可以收发的 Channel 时,直接处理该 Channel 对应的
case
; - 当不存在可以收发的 Channel 时,执行
default
中的语句;
当我们运行下面的代码时就不会阻塞当前的 Goroutine,它会直接执行 default
中的代码。
func main() {
ch := make(chan int)
select {
case i := <-ch:
println(i)
default:
println("default")
}
}
$ go run main.go
default
非阻塞的 Channel 发送和接收操作还是很有必要的,在很多场景下我们不希望 Channel 操作阻塞当前 Goroutine,只是想看看 Channel 的可读或者可写状态,如下所示:
errCh := make(chan error, len(tasks))
wg := sync.WaitGroup{}
wg.Add(len(tasks))
for i := range tasks {
go func() {
defer wg.Done()
if err := tasks[i].Run(); err != nil {
errCh <- err
}
}()
}
wg.Wait()
select {
case err := <-errCh:
return err
default:
return nil
}
示例程序:
func main() {
ch := make(chan int)
go func() {
for range time.Tick(1 * time.Second) {
ch <- 0
}
}()
for {
select {
case <-ch:
println("case1")
case <-ch:
println("case2")
}
}
}
$ go run main.go
case1
case2
case1
...
可以看出,select 中的case不是用来判断的,而是检测通道的状态。
3. go语言循环语句
go只有一种for循环,类似于java的写法,也支持foreach的写法:
常规写法:
for init; condition; post { }//和 C 语言的 for 一样
for condition { }//和 C 的 while 一样
for { }//和 C 的 for(;;) 一样
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
fmt.Println(i)
}
}
------------------
C:\Users\11965\AppData\Local\JetBrains\GoLand2023.2\tmp\GoLand\___go_build_main_go__1_.exe
0
1
2
3
4
5
6
7
8
9
也可以向python一样,同时遍历map和数组的key,value值(数组的key就是下标啦):
同时遍历k,v:
for key, value := range oldMap {
newMap[key] = value
}
只遍历k:
for key := range oldMap
只遍历value:
for _, value := range oldMap
示例放在基本数据结构中进行演示
4.go语言函数
一般定义:
func 函数名(参数1 [类型,可省略], 参数2 [类型,可省略]) 返回值1,返回值2{
}
函数式编程定义:
package main
import (
"fmt"
"math"
)
func main(){
/* 声明函数变量 */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* 使用函数 */
fmt.Println(getSquareRoot(9))
}
--------
81
可以看到,go语言的函数定义中可以省略类型规定,又可以同时返回多个值。
示例程序:
package main
import "fmt"
func main() {
/* 定义局部变量 */
var a int = 100
var b int = 200
var ret int
/* 调用函数并返回最大值 */
ret = max(a, b)
fmt.Printf("最大值是 : %d\n", ret)
}
/* 函数返回两个数的最大值 */
func max(num1, num2 int) int {
/* 定义局部变量 */
var result int
if num1 > num2 {
result = num1
} else {
result = num2
}
return result
}
---------------------
最大值是 : 200
同样的,go语言也分函数作用域,传进函数的一般是形式参数,不会改变原有的值,如果需要传递实参,需要加上指针符号来进行实现
t)
}
/* 函数返回两个数的最大值 /
func max(num1, num2 int) int {
/ 定义局部变量 */
var result int
if num1 > num2 {
result = num1
} else {
result = num2
}
return result
}
最大值是 : 200
**同样的,go语言也分函数作用域,传进函数的一般是形式参数,不会改变原有的值,如果需要传递实参,需要加上指针符号来进行实现**