go中len和Count的区别

最近使用go lang, 用着特别爽。但最近开发一个模块,一直不符合预期。后面通过看go源码,发现趟着大坑了。

len或者Count都能获取字符串、字节数组长度。如

data := “hello”

data_len := len(data)

data_len := strings.Count(data, “”) – 1

content := []byte(“hello”)

content_len := len(content)

content_len := bytes.Count(content, nil) – 1

但是len和Count还是有区别。以bytes为例,使用bytes.Count(data, nil) – 1获取字节数组data长度,长度值为utf8.RuneCount(data) + 1,返回的utf-8编码的长度;而len返回实际字节长度。字符串类似。

go lang 获取本机ip

方法一

func GetIp() {
    addrs, _ := net.InterfaceAddrs()
    log.Println(addrs)

    for _, addr := range addrs {
        if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                log.Println(ipnet.IP.String())
            }
        }
    }
}

但是这个方法有个问题,如果本机存在虚拟机、docker等虚拟网卡,这类的ipv4地址同样能获取到

改进下,使用方法二

func GetIpV3() (string, error) {
    addrs, _ := net.Interfaces()
    //log.Println(addrs)

    for _, addr := range addrs {
        if addr.Flags & net.FlagUp == 0 {
            continue
        }

        if addr.Flags & net.FlagLoopback == 1 {
            continue
        }

        if !strings.Contains(addr.Name, "eth") {
            continue
        }

        addr_list, _ := addr.Addrs()
        //log.Println(addr.Name)

        for _, address := range addr_list {
            if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
                if ipnet.IP.To4() != nil {
                    //log.Println(ipnet.IP.String())
                    return ipnet.IP.String(), nil
                }
            }
        }
    }

    return "", errors.New("valid ip not found")
}

对网卡进行过滤。