单分支

if condition {
    代码块
}
if 5 > 2 {
    fmt.Println("5 greater than 2")
}

Go语言中,花括号一定要跟着if、for、func等行的最后,否则语法出错。

condition必须是一个bool类型,在Go中,不能使用其他类型等效为布尔值。 if 1 {} 是错误的

语句块中可以写其他代码

如果condition为true,才能执行其后代码块

多分支

if condition1 {
    代码块1
} else if condition2 {
    代码块2
} else if condition3 {
    代码块3
} ... {
    ...
} else if conditionN {
    代码块N
} else {
    代码块
}

多分支结构,从上向下依次判断分支条件,只要一个分支条件成立,其后语句块将被执行,那么其他条件都不会被执行

前一个分支条件被测试过,下一个条件相当于隐含着这个条件 一定要考虑一下else分支是有必要写,以防逻辑漏洞

循环也可以互相嵌套,形成多层循环。循环嵌套不易过深。

if score, line := 99, 90; score > line {
 fmt.Println("perfect")
} else {
 fmt.Println("good")
} // score, line作用域只能是当前if语句

// 这种写法中定义的变量作用域只能是当前if或switch。

switch分支// Go语言的switch有别于C语言的switch,case是独立代码块,不能穿透。

a := 20
switch a { // 待比较的是a
case 10:
 fmt.Println("ten")
case 20:
 fmt.Println("twenty")
case 30, 40, 50: // 或关系
 fmt.Println(">=30 and <=50")
default:
 fmt.Println("other")
}
switch a:=20;a { // 待比较的是a
case 10:
 fmt.Println("ten")
case 20:
 fmt.Println("twenty")
case 30, 40, 50: // 或关系
 fmt.Println(">=30 and <=50")
default:
 fmt.Println("other")
}
a := 20
switch { // 没有待比较变量,意味着表达式是true,是布尔型
case a > 0:
 fmt.Println("positive")
case a < 0:
 fmt.Println("negative")
default:
 fmt.Println("zero")
}
switch a := 20; { // 没有待比较变量,意味着表达式是true,是布尔型
case a > 0: // 如果待比较值是true,a > 0如果返回true,就进入
 fmt.Println("positive")
 // fallthrough // 穿透
case a < 0: // 如果待比较值是true,a < 0如果返回true,就进入
 fmt.Println("negative")
default:
 fmt.Println("zero")
}

 

for循环

 

for [初始操作];[循环条件];[循环后操作] {
    循环体
}

 

初始操作:第一次进入循环前执行,语句只能执行一次,之后不再执行

循环条件:要求返回布尔值,每次进入循环体前进行判断。如果每次条件满足返回true,就进入循 环执行一次循环体;否则,循环结束

循环后操作:每次循环体执行完,在执行下一趟循环条件判断之前,执行该操作一次

for i := 5; i < 10; {}
for i := 5; ; {} // 没条件就相当于true
for i < 10 {} // for condition {},condition就是循环条件
for ;; {} // 死循环
// 死循环简写如下
for {} // 死循环 相对于 for true {}

continue

 中止当前这一趟循环体的执行,直接执行“循环后操作”后,进入下一趟循环的条件判断。

break

终止当前循环的执行,结束了。

 for range

类型 变量 range表达式 第一个值 第二个值
数组或切片 a [n]E, *[n]E []E int类型的index a[i] E
字符串 s "abcd" index i int utf-8字节偏 移 unicode值 rune
map m map[K]V key value

 

 

 

 

 

 随机数

 标准库"math/rand" 使用的是伪随机数,是内部写好的公式计算出来的。这个公式运行提供一个种子,有这个种子作为 起始值开始计算。

 src := rand.NewSource(100),使用种子100创建一个随机数源

rand.New(rand.NewSource(time.Now().UnixNano())) ,利用当前时间的纳秒值做种子

r10 := rand.New(src),使用源创建随机数生成器

r10.Intn(5),返回[0, 5)的随机整数

// 对于go1.20*之前的版本,采用这种方法会导致每次生成的随机数都是一样的
// 这是因为之前的版本所使用的全局随机数生成器globalRand的种子默认是1
    for i := 0; i < 10; i++ {
        fmt.Println(rand.Intn(10) - 8) // 伪随机数,每次都一样,go1.20版本开始就不一样了,就是真随机数了
    }

它的种子默认为1, var globalRand = New(&lockedSource{src: NewSource(1). (*rngSource)})

如果要改变globalRand的种子,就需要使用rand.Seed(2)修改种子

rand.Intn(5)就是使用它生成随机数

下面是go1.20之前版本的原码:

 从Go v1.20开始,globalRand已经改变为使用随机种子。参看Release notes https://go.dev/doc/go1.2 0

下面是go1.20.4版本的原码:

 

如果想使用旧版globalRand的行为,可以手动设定种子源 rand.Seed(1) 或使用环境变量os.Setenv("GODEBUG", "randautoseed=0") 。

 

posted on 2023-05-29 14:52  自然洒脱  阅读(84)  评论(0编辑  收藏  举报