• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Go出现panic的场景

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

概述

go中发生panic的场景:
- 数组/切片越界
- 空指针调用。比如访问一个 nil 结构体指针的成员
- 过早关闭 HTTP 响应体
- 除以 0
- 向已经关闭的 channel 发送消息
- 重复关闭 channel
- 关闭未初始化的 channel
- 未初始化 map。注意访问 map 不存在的 key 不会 panic,而是返回 map 类型对应的零值,但是不能直接赋值
- 跨协程的 panic 处理
- sync 计数为负数。
- 类型断言不匹配。`var a interface{} = 1; fmt.Println(a.(string))` 会 panic,建议用 `s,ok := a.(string)`

代码

package a_panics

import (
    "fmt"
    "math/rand"
    "testing"
    "time"
)

type Student struct {
    Name string
    Age  int
}

func TestP0(t *testing.T) {
    // 空指针调用: 访问一个 nil 结构体指针的成员
    var s *Student
    fmt.Println(s.Name)
}

func TestP1(t *testing.T) {

    // 除数为0
    fmt.Println(100 / 0)

    // rand.Intn方法:如果里面的参数 <=0 的话,会panic
    rand.Seed(time.Now().UnixNano())
    fmt.Println(rand.Intn(0))

    // 数组/切片越界
    lst := []string{"whw", "naruto", "sasuke"}
    fmt.Println(lst[0:22])

    // 为初始化map
    var m1 map[string]interface{}
    fmt.Println(m1["name"]) // 直接取值不会panic
    m1["age"] = 22
    /*
        // 下面这样可以
        m1 := make(map[string]interface{}, 0)
        m1["age"] = 22
    */

    // 断言类型不匹配
    var a interface{} = 1
    fmt.Println(a.(string))
    /*
        // 建议这样写:
        s,ok := a.(string)
        fmt.Println("ok: ", ok, "s: ", s)
    */

}

~~~

package a_panics

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "testing"
)

func TestHttpBody(t *testing.T) {

    url := "https://www.baidu.com"
    method := "GET"

    client := &http.Client{}
    req, err := http.NewRequest(method, url, nil)

    if err != nil {
        fmt.Println(err)
        return
    }

    res, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
        return
    }

    // TODO (不加defer)过早关闭HTTP响应体
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(body))
}

~~~

package a_panics

import "fmt"

import "testing"

func TestChannel0(t *testing.T) {

    //ch := make(chan int)
    // 关闭未初始化的channel
    var ch chan int
    close(ch)

}

func TestChannel1(t *testing.T) {

    ch := make(chan int) // no-cached channel
    go func() {
        // 子goroutine中向channel中存放值
        ch <- 1
        close(ch)
    }()
    // 主 goroutine 接收channel的值
    x := <-ch
    fmt.Println("x: ", x)

    // TODO // 像已关闭的channel发送消息
    ch <- 2
}

func TestChannel2(t *testing.T) {

    ch := make(chan int) // no-cached channel
    go func() {
        // 子goroutine中向channel中存放值
        ch <- 1
        close(ch)
    }()
    // 主 goroutine 接收channel的值
    x := <-ch
    fmt.Println("x: ", x)

    // TODO 重复关闭channel
    close(ch)
}

~~~

package a_panics

import (
    "fmt"
    "testing"
)

func test(){

    defer func(){
        // 捕获异常
        if err := recover(); err != nil{
            fmt.Println("errFromFunc:test", err)
        }
    }()

    var m1 map[string]interface{}
    m1["age"] = 22
}

func sayHello(){
    fmt.Println("hello!")
}

func TestP4(t *testing.T){

    go test()
    go sayHello()

}

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
windows如何配置Go环境(Ziparchive方式)?发布时间:2022-07-10
下一篇:
Go项目实战:打造高并发日志采集系统(五)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap