072-火箭发射游戏

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q1007729991/article/details/80994093

不知不觉,Golang 之路已经走过了一大半。谢谢所有读者一路陪伴,也很欣慰你们能一直坚持下来。接下来,我们进入几篇比较轻松的话题,我不打算在这里全盘托出,让我们从一个火箭发射小游戏开始吧。同样,这个例子来源于《Golang 程序设计》。

1. 小小发射器

当然,我们并不是真的要开发一套火箭发射程序的代码,只是简单的模拟一下。这对你来说几乎就是小学生的作业。我们的目标如下:

  • 从 10 开始倒计时,每隔一秒屏幕打一个数字。10,9,8,7,6,5,4,3,2,1
  • 倒计时完成,在屏幕打印 launch
  • 当我按下键盘的 Enter 键时,屏幕会打印 “abort”,并退出。

这个程序对你来说,简直就是小儿科。你打算怎样写呢?像下面这样?

package main
import (
    "fmt"
    "time"
)
func main() {
    for n := 10; n > 0; n-- {
        fmt.Println(n)
        time.Sleep(1 * time.Second)
    }
    fmt.Println("launch")
}

好的,太聪明了,没问题。不过还有第三个功能没实现,想来想去,感觉也不知道怎么加?没事,我们稍微再改动一下上面的程序,第三个功能最后再说。

先把上面的代码改成 channel 版本的:

package main

import (
    "fmt"
    "time"
)

func main() {
    // time.Tick 返回一个 <-chan Time 类型的 channel
    // 这个 channel 每隔固定时间,吐出一个时间。这里我设置的 1 秒。
    tick := time.Tick(1 * time.Second)
    for n := 10; n > 0; n-- {
        fmt.Println(n)
        <-tick
    }
    fmt.Println("launch")
}

嗯,看起来理解上应该没有问题,最后。下面我们需要完成第三个功能,得祭出新杀器 —— select.

2. select

学习过 Linux 环境编程的同学,对 select 一定不陌生,它是一种 IO 多路复用技术。在 Golang 里,select 也是这个意思,不过使用起来会更加方便。

package main

import (
    "fmt"
    "os"
    "time"
)

func main() {
    tick := time.Tick(1 * time.Second)
    abort := make(chan struct{})

    go func() {
        os.Stdin.Read(make([]byte, 1))
        abort <- struct{}{}
    }()

    for n := 10; n > 0; n-- {
        // 有意思的是,一旦 tick 或者 abort 这两个 channel 有任何一个可读了,
        // 那么就会进入相应的 case 分支
        select {
        case <-tick:
            fmt.Println(n)
        case <-abort:
            fmt.Println("abort")
            return
        }
    }
    fmt.Println("launch")
}

这个程序,完美的解决了 Enter 键随时取消发射的功能。select 在上面的作用就是监听所有的 case 分支的 channel,它非常像 switch case 语句。select case 的语法结构如下:

select {
case <-ch1:
    // ...
case x := <-ch2:
    // ...
case ch3 <- y:
    // ...
default:
    // ...
}

只要任何一个 case 语句后面的 channel 可读或可写,那它就会进入相应的 case 分支执行。如果同时有多个 case 后面的 channel 可读可写,golang 会随机的选择一个 case 分支执行。

如果你写了 default 语句,那进入 select 后,如果所有 case 都不成立,就执行 default 语句。

3. 总结

  • 掌握 select 语法

猜你喜欢

转载自blog.csdn.net/q1007729991/article/details/80994093