droxlzcgnr639823 2018-10-04 11:30
浏览 36
已采纳

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

I am new to golang. My program panics after I try to catch an error in the main block after getting location defined. I have read somewhere, adding defer.close() might help, but again the compiler says no such definition exists in your struct Help me resolve it.

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条回答 默认 最新

  • duandui2803 2018-10-04 11:53
    关注

    Your ForeignIP() returns *IPInfo which is a struct of pointer type but you're getting error from this line of code response, err := http.Get("http://ipinfo.io" + ip + "/json") which is failed due to below error:

    dial tcp: lookup ipinfo.io172.16.11.115: no such host.

    Then you return nil over there like.

       if err != nil {
                return nil , err
       }
    

    And you access the value of nil as:

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

    So nil value has not any IP or City variable that is why it panic. So you need to return struct which is of pointer type then you can access the variable IP and City from location response, here I'm modifying the code.

    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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮