在主块中捕获到错误后,程序会出现紧急情况。紧急:运行时错误:无效的内存地址或nil指针取消引用

时间:2018-10-04 11:30:02

标签: go

我是golang的新手。在尝试定义位置后,尝试在主块中捕获错误后,程序出现了紧急情况。我读过某个地方,添加defer.close()可能会有所帮助,但再次编译器说您的结构中不存在这样的定义。

type IPInfo struct {

    IP string

    Hostname string

    City string
    Country string

    Loc string
    Org string
    Postal string
}
func main() {
        ip := getLocalIpv4()
        location, err := ForeignIP(ip)
        if err != nil {
            fmt.Println("error bro")
        }

    fmt.Println("ip address of this machine is ", location.IP)
    fmt.Println(" city of this machine is ", location.City)

}

// MyIP provides information about the public IP address of the client.
func MyIP() (*IPInfo, error) {
    return ForeignIP("")
}

// ForeignIP provides information about the given IP address,
// which should be in dotted-quad form.
func ForeignIP(ip string) (*IPInfo, error) {
    if ip != "" {
        ip += "/" + ip
    }
    response, err := http.Get("http://ipinfo.io" + ip + "/json")
    if err != nil {
        return nil, err
    }
    defer response.Body.Close()

    contents, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return nil, err
    }
    var ipinfo IPInfo
    if err := json.Unmarshal(contents, &ipinfo); err != nil {
        return nil, err
    }
    return &ipinfo, nil
}

// retrieves ip address of local machine
func getLocalIpv4() string {
    host, _ := os.Hostname()
    addrs, _ := net.LookupIP(host)
    for _, addr := range addrs {
        if ipv4 := addr.To4(); ipv4 != nil {
            return fmt.Sprintf("%s", ipv4)
        }
    }
    return "localhost"
}

1 个答案:

答案 0 :(得分:1)

您的ForeignIP()返回*IPInfo,它是指针类型的结构,但是您从这行代码response, err := http.Get("http://ipinfo.io" + ip + "/json")中遇到错误,由于以下错误而失败:

  

拨号TCP:查找ipinfo.io172.16.11.115:没有此类主机。

然后,您像在那儿一样返回nil

   if err != nil {
            return nil , err
   }

您将nil的值访问为:

location, err := ForeignIP(ip)
fmt.Println("ip address of this machine is ", location.IP)
fmt.Println(" city of this machine is ", location.City)

因此nil值没有任何IPCity变量,这就是为什么它会慌张的原因。因此,您需要返回指针类型的struct,然后可以从IP响应中访问变量Citylocation,这里我正在修改代码。

func ForeignIP(ip string) (*IPInfo, error) {
    var ipinfo IPInfo
    if ip != "" {
        ip += "/" + ip
    }
    response, err := http.Get("http://ipinfo.io" + ip + "/json")
    if err != nil {
        return &ipinfo , err
    }

    defer response.Body.Close()

    contents, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return &ipinfo, err
    }

    if err := json.Unmarshal(contents, &ipinfo); err != nil {
        return &ipinfo, err
    }
    return &ipinfo, nil
}