1. 第一百零一天
1.关于循环语句,下面说法正确的有?
- A. 循环语句既支持 for 关键字,也支持 while 和 do-while;
- B. 关键字for的基本使用方法与C/C++中没有任何差异;
- C. for 循环支持 continue 和 break 来控制循环,但是它提供了一个更高级的 break,可以选择中断哪一个循环;
- D. for 循环不支持以逗号为间隔的多个赋值语句,必须使用平行赋值的方式来初始化多个变量;
参考答案及解析:CD。
2.下面代码的功能是从小到大找出 17 和 38 的 3 个公倍数,请问下面的代码有什么问题?
var ch chan int = make(chan int)
func generate() {
for i := 17; i < 5000; i += 17 {
ch <- i
time.Sleep(1 * time.Millisecond)
}
close(ch)
}
func main() {
timeout := time.After(800 * time.Millisecond)
go generate()
found := 0
for {
select {
case i, ok := <-ch:
if ok {
if i%38 == 0 {
fmt.Println(i, "is a multiple of 17 and 38")
found++
if found == 3 {
break
}
}
} else {
break
}
case <-timeout:
fmt.Println("timed out")
break
}
}
fmt.Println("The end")
}
参考答案即解析:break 会跳出 select 块,但不会跳出 for 循环。这算是一个比较容易掉的坑。可以使用 break label 特性或者 goto 功能解决这个问题,这里使用 break label 作个示例。
var ch chan int = make(chan int)
func generate() {
for i := 17; i < 5000; i += 17 {
ch <- i
time.Sleep(1 * time.Millisecond)
}
close(ch)
}
func main() {
timeout := time.After(800 * time.Millisecond)
go generate()
found := 0
MAIN_LOOP:
for {
select {
case i, ok := <-ch:
if ok {
if i%38 == 0 {
fmt.Println(i, "is a multiple of 17 and 38")
found++
if found == 3 {
break MAIN_LOOP
}
}
} else {
break MAIN_LOOP
}
case <-timeout:
fmt.Println("timed out")
break MAIN_LOOP
}
}
fmt.Println("The end")
}