Go语言实战 | 青训营笔记

75 阅读2分钟
package main  
  
import (  
"bufio"  
"fmt"  
"math/rand"  
"os"  
"strconv"  
"strings"  
"time"  
)  
  
func main() {  
    rand.Seed(time.Now().UnixNano())  
    rd := rand.Intn(100)  
    fmt.Printf("%d rand \n", rd)  
    fmt.Println("Please input your guess")  
    reader := bufio.NewReader(os.Stdin)  
    raw, err := reader.ReadString('\n')  
    if err != nil {  
        fmt.Println("error input")  
        return  
    }  
    raw = strings.TrimSuffix(raw, "\r\n")  

    number, err := strconv.Atoi(raw)  
    if err != nil {  
        fmt.Println("conv is error ")  
        return  
    }  
    fmt.Printf("your guess: %d\n", number)  

}

今天把基础实战课程的猜数字做了一下,基本的框架就是先使用rand生成一个随机数,但是rand是有讲究的需要用先调用seed函数放入一个种子,防止生成的数字重复,然后使用bufio读取用户在控制台的输入,判断是否是错误的输入格式,如果是错误的格式直接就报错,否则就将它格式化一下,删除它的后缀,同时转换成int类型判断是否猜中。

进一步的优化就是,把这个程序改为for循环的模式,因为上述的程序段只能进行一次的猜。然后对他猜的值进行判断如果猜正确退出程序。

除了完成这个demo小程序,我还学了一些go 并发编程的知识

package main  
  
import (  
"fmt"  
"sync"  
)  
  
var i = 1  
var wgs sync.WaitGroup  
  
var lock sync.Mutex  
  
func inc() {  
    defer wgs.Done()  
    lock.Lock()  
    i++  
    fmt.Println(i)  
    lock.Unlock()  
}  
  
func dec() {  
    defer wgs.Done()  
    lock.Lock()  
    i--  
    fmt.Println(i)  
    lock.Unlock()  
}  
  
func main() {  
    for i := 0; i < 10000; i++ {  
        wgs.Add(1)  
        go inc()  
        wgs.Add(1)  
        go dec()  
    }  
    wgs.Wait()  
    fmt.Printf("i = %d\n", i)  
}

运用到了sync.Mutex 这是一个简单的买票模拟程序 Mutex实现的是加锁的功能,当进行inc或者dec方法的时候,进行上锁操作,因为i++ 与i--的操作并非是原子操作的,所以是有线程安全问题的,可能会出现减到负数的情况,所以需要进行上锁操作,同时使用了 WaitGroup防止线程未执行结束,main线程就直接结束了程序,在inc与dec的函数内需要配合defer 进行wgs.Done()操作否则main线程将会一直阻塞造成死锁。