go

一:文件操作

1.1:打开和关闭文件,读内容

func main() {
    //打开文件
    openFileObj, err := os.Open("text.txt")
    if err!=nil{
        fmt.Println("open file failed")
        return
    }
    defer openFileObj.Close()//关闭文件
}

1.2:打开文件读内容

1.2.1:read方法读文件

func readFromFile()  {
    //读文件
    readFileObj, err := os.Open("text.txt")
    if err!=nil{
        fmt.Println("open file failed")
        return
    }
    defer readFileObj.Close()//关闭文件
    //读文件
    //var tmp=make([]byte,128)//指定读的长度
    //openFileObj.Read(tmp)
    //上面两句也等于下面的写法
    var tmp [128]byte
    for   {
        n, err := readFileObj.Read(tmp[:])
        if err==io.EOF{
            fmt.Println("读完了")
            return
        }
        if err !=nil{
            fmt.Println("read file failed",err)//EOF是end of file,读到文件末尾了
            return
        }
        fmt.Printf("读了%d个字节\n",n)
        fmt.Println(string(tmp[:n]))//转换为字符串
        if n<128 {//读128个字节
            return
        }
    }
}

 

1.2.2:bufio读文件,一行一行读写

func readFromFileBufio()  {
    readFileObj, err := os.Open("text.txt")
    if err!=nil{
        fmt.Println("open file failed")
        return
    }
    defer readFileObj.Close()//关闭文件
    newReader := bufio.NewReader(readFileObj)//创建一个从文件中读取内容的对象
    for {//使用for循环读
        line, err := newReader.ReadString('\n') //注意是字符
        if err == io.EOF {
            if len(line) != 0 {
                fmt.Println(line)
            }
            fmt.Println("文件读完了")
            break
        }
        if err != nil {
            fmt.Println("readFromFileByBufio failed, err:", err)
            return
        }
        fmt.Print(line)
    }

}

1.2.3:ioutil读取整个文件

func readFileByIoutil()  {
    ret, err := ioutil.ReadFile("text.txt")//直接就打开文件
    if err!=nil {
        fmt.Printf("read file failed,err:%v",err)
        return
    }
    fmt.Println(string(ret))//转换为字符串
}

1.3:写文件

 写文件的方式:

 

 1.3.1:write和writestring写文件

func writeFile() {
    //打开文件,如果没有这个文件就会创建一个
    fileObj, err := os.OpenFile("text.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) //文件,写的方式,八进制数
    if err != nil {
        fmt.Printf("open file failed,err:%v", err)
        return
    }
    fileObj.Write([]byte("Write 写的是字节\n"))
    fileObj.WriteString("WriteString写的是字符串")
    fileObj.Close() //关闭文件,可以使用defer,也可以直接关闭
}

1.3.2:bufio.NewWriter

func writeFileByBufio() {
    fileObj, err := os.OpenFile("t3.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) //文件,写的方式,八进制数
    if err != nil {
        fmt.Println("open file failed", err)
        return
    }
    defer fileObj.Close()//要用defer才能够写进去
    writer := bufio.NewWriter(fileObj)
    for i := 0; i < 10; i++ {
        writer.WriteString("沙河\n") //将数据先写入缓存
    }
    writer.Flush() //将缓存中的内容写入文件
}

1.3.3:ioutil.WriteFile

func writeFileByIoutil() {
    str := "writeFileIoutil"
    err := ioutil.WriteFile("t1.txt", []byte(str), 0666)
    if err != nil {
        fmt.Printf("open file failed,err:%v", err)
        return
    }
}

 二:strconv标准介绍

//从字符串中解析为整形的数据
    str1 := "1000"                                  //必须声明是字符串类型的,否则会报错
    parseInt, err := strconv.ParseInt(str1, 10, 64) //转为10进制64位的
    if err != nil {
        fmt.Println("parseInt failed,err:", err)
    }
    fmt.Printf("%#v", parseInt)

    //把数字转换为字符串
    str2:= int32(97)
    ret1 := fmt.Sprintf("%d", str2)
    fmt.Printf("%v",ret1)
    //ret1:=string(str2) //go语言中是不能用string转换为字符串的

    //字符串转换位数字
    ret2, _ := strconv.Atoi(str1)
    fmt.Println(ret2)

    //数字转换位字符串
    i:=97
    ret3 := strconv.Itoa(i)
    fmt.Printf("%v",ret3)

    //从字符串中解析出布尔值
    boolStr:="true"
    boolValue, _ := strconv.ParseBool(boolStr)
    fmt.Printf("%#v",boolValue)

    //从字符串中解析出浮点数
    floatStr:="1.23"
    floatValue, err := strconv.ParseFloat(floatStr,64)//转换为64的float
    fmt.Printf("%#v",floatValue)

 三:并发编程

Go语言的并发通过goroutine实现。goroutine类似于线程,属于用户态的线程,我们可以根据需要创建成千上万个goroutine并发工作。goroutine是由Go语言的运行时(runtime)调度完成,而线程是由操作系统调度完成。

Go语言还提供channel在多个goroutine间进行通信。goroutine和channel是 Go 语言秉承的 CSP(Communicating Sequential Process)并发模式的重要实现基础。

goroutine什么时候结束:goroutine对应的函数结束了,goroutine就结束了,main函数执行完了,由main函数创建的那些goroutine都结束了

3.1:使用goroutine

func main() {
    for i:=0; i<10;i++  {
        go hello(i)//函数前面加一个go是实现goroutine,开始一个单独的goroutine去执行hello函数
    }
    fmt.Println("main")//此时只会输出main,本来是按顺序执行的,但是加了一个go之后会后执行,打印mian,打印完之后就结束了
    //main都结束了,其他的也就结束了,要打印hello的话,此时要开启一个sleep
    time.Sleep(time.Second)//括号里面不能直接写1,写1的话是纳秒,会非常的快
}
func hello(i int)  {
    fmt.Println("使用goroutine")
}

//改成匿名函数
func main() {
    for i:=0; i<10;i++  {
        go func(i int) {
            fmt.Println(i)
        }(i) 
    }
    fmt.Println("main")
    time.Sleep(time.Second)
}

3.1.2:使用了sync.WaitGroup来实现goroutine的同步

var wg sync.WaitGroup
func main() {
    for i := 0; i < 10; i++ {
        wg.Add(1) // 启动一个goroutine就登记+1
        go f1(i)
    }
    wg.Wait()// 等待所有登记的goroutine都结束
}
func f1(i int) {
    defer wg.Done() //也可以这样子写
    time.Sleep(time.Second * time.Duration(rand.Intn(10)))
    fmt.Println(i)
    //wg.Done() // goroutine结束就登记-1
}

 

3.1.3:math/rand随机数

func randNum() {
    rand.Seed(time.Now().UnixNano()) //因为每次执行,产生的随机数都是一样,所以加一个seed种子,time.Now().UnixNano()这个数一个int64的数数
    for i := 0; i < 10; i++ {
        ret1 := rand.Int()
        ret2 := rand.Intn(10) //产生一个包括0,不包括10的随机数
        fmt.Println(ret1, ret2)
        fmt.Println(0-ret1, 0-ret2)//用0减去这个数就是负数
    }
}

生成随机种子

//这两种是相等的
func main() {
    source := rand.NewSource(time.Now().UnixNano()) // 使用当前的纳秒生成一个随机源,也就是随机种子
    ran := rand.New(source)                         // 生成一个rand
    fmt.Println(ran.Int())                          // 获取随机数
}
//func main() {
//    // 直接调用rand的方法生成伪随机int值
    rand.Seed(time.Now().Unix()) // 设置种子,我们以当前时间的秒;当然也可以用毫秒,微秒等
    fmt.Println(rand.Int())
    fmt.Println(rand.Int31())
    fmt.Println(rand.Intn(5))
}

 

3.1.4:goroutine调度模型GMP

var wg sync.WaitGroup
func main() {
    runtime.GOMAXPROCS(1)//设置当前程序并发时占用的cpu数,默认是cpu的逻辑核心数,默认跑满cpu
    //runtime.NumCPU()//打印cpu的线程数
    wg.Add(1)
    go f1()
    go f2()
    wg.Wait()
}
func f1() {
    defer wg.Done()
    for i:=0; i<10;i++{
        fmt.Printf("A:%d\n",i)
    }

 3.2:channel

 3.4:error错误

第一种:通过errors包去订制erro
error := errors.New("hello,error")//使用errors必须import "errors"包
    if error != nil {
        fmt.Print(error)
    }
第二种:通过fmt.Errorf()去订制
err := fmt.Errorf("hello error")
    if err != nil {
        fmt.Print(err)
    }
第三种:就是通过自定义的MyError块去订制了
func main() {
    err := MyError{
        errors.New("hello error"),
    }
    fmt.Println(err.Error())
}
type MyError struct {
    err error
}
//订制Error()
func (e MyError) Error() string {
    return e.err.Error()
}

 

posted @ 2020-04-03 13:48  柠檬abcd  阅读(163)  评论(0编辑  收藏  举报