了解 Go 的 net/netip Addr 类型:深入探讨

了解 go 的 net/netip addr 类型:深入探讨

Go语言的net/netip包提供了一种更现代、更高效的方式来处理IP地址,其核心是Addr类型。本文将深入探讨Addr类型及其使用方法,并与旧的net.IP类型进行对比。

为什么选择net/netip.Addr?

net.IP类型的一些缺点促使了Addr类型的诞生:

可变性:net.IP是可变的,需要堆分配,这会影响性能和内存管理。无效状态:net.IP可能包含无效状态,需要额外的代码来处理。比较困难:使用==运算符无法可靠地比较net.IP。

Addr类型解决了以上所有问题。它是一个值类型(不可变),始终代表有效的IP地址,简化了代码并提升了性能。

Addr类型入门

以下是如何创建和使用Addr类型的基本示例:

package mainimport (    "fmt"    "net/netip")func main() {    // 从字符串创建Addr    addr, err := netip.ParseAddr("192.168.1.1")    if err != nil {        panic(err)    }    // 如果输入已知有效,可以使用mustParseAddr    addr2 := netip.MustParseAddr("2001:db8::1")    fmt.Printf("IPv4: %vIPv6: %v", addr, addr2)}

登录后复制

ParseAddr函数严格验证输入,拒绝无效的IP地址格式。

深入研究Addr方法

接下来,我们探索一些常用的Addr方法。

判断IPv4或IPv6

func checkAddrType(addr netip.Addr) {    if addr.Is4() {        fmt.Println("这是IPv4地址")        bytes := addr.As4()        fmt.Printf("字节表示:%v", bytes)    } else if addr.Is6() {        fmt.Println("这是IPv6地址")        bytes := addr.As16()        fmt.Printf("字节表示:%v", bytes)    }}

登录后复制

对于IPv4映射的IPv6地址(例如::ffff:192.0.2.1),可以使用Is4In6()进行检测。

地址分类方法

Addr类型提供了一系列方法用于对IP地址进行分类:

func classifyAddress(addr netip.Addr) {    checks := []struct {        name string        fn   func() bool    }{        {"IsGlobalUnicast", addr.IsGlobalUnicast},        {"IsPrivate", addr.IsPrivate},        {"IsLoopback", addr.IsLoopback},        {"IsMulticast", addr.IsMulticast},        {"IsLinkLocalUnicast", addr.IsLinkLocalUnicast},        {"IsLinkLocalMulticast", addr.IsLinkLocalMulticast},        {"IsInterfaceLocalMulticast", addr.IsInterfaceLocalMulticast},        {"IsUnspecified", addr.IsUnspecified},    }    for _, check := range checks {        if check.fn() {            fmt.Printf("地址是 %s", check.name)        }    }}

登录后复制

例如,编写一个绑定到非环回接口的服务:

func getBindableAddresses(addrs []netip.Addr) []netip.Addr {    var bindable []netip.Addr    for _, addr := range addrs {        if !addr.IsLoopback() && !addr.IsLinkLocalUnicast() {            bindable = append(bindable, addr)        }    }    return bindable}

登录后复制

处理区域(IPv6范围ID)

IPv6地址可能包含区域信息:

func handleZones() {    // 创建带有区域的地址    addr := netip.MustParseAddr("fe80::1%eth0")    // 获取区域    zone := addr.Zone()    fmt.Printf("区域: %s", zone)    // 比较带有区域的地址    addr1 := netip.MustParseAddr("fe80::1%eth0")    addr2 := netip.MustParseAddr("fe80::1%eth1")    // 由于区域不同,这两个地址不同    fmt.Printf("相同的地址?%v", addr1 == addr2) // false    // withZone创建具有不同区域的新地址    addr3 := addr1.WithZone("eth2")    fmt.Printf("新的区域: %s", addr3.Zone())}

登录后复制

实际应用:IP地址过滤器

以下是一个简单的IP地址过滤器示例:

type IPFilter struct {    allowed []netip.Addr    denied  []netip.Addr}func NewIPFilter(allowed, denied []string) (*IPFilter, error) {    f := &IPFilter{}    // ... (解析allowed和denied地址,类似之前的例子) ...    return f, nil}func (f *IPFilter) IsAllowed(ip string) bool {    addr, err := netip.ParseAddr(ip)    if err != nil {        return false    }    // ... (检查denied和allowed列表) ...    return false}

登录后复制

性能考量

net/netip.Addr的性能优势在于其值类型特性:

无堆分配:基本操作无需堆分配,提高效率。高效比较:比较操作高效。零值无效:零值表示无效地址,避免了net.IP中零值可能有效的问题。

常见问题和技巧

避免混淆net.IP和netip.Addr。注意区域对地址比较的影响。谨慎使用MustParseAddr。记住Addr是不可变的。

接下来

本文介绍了net/netip.Addr的基础知识和高级用法。后续文章将探讨AddrPort类型,它结合了IP地址和端口号。

以上就是了解 Go 的 net/netip Addr 类型:深入探讨的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2310122.html

(0)
上一篇 2025年2月28日 11:53:06
下一篇 2025年2月24日 22:00:54

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • GoFr:一个有主见的微服务开发框架

    在快速发展的软件开发领域,微服务架构彻底改变了应用的设计和部署方式。GoFr应运而生,它是一个功能强大的、注重实效的微服务开发框架,旨在简化和标准化微服务的创建流程。本文将深入探讨GoFr如何成为开发人员和组织的革新力量。 GoFr是什么?…

    2025年2月28日
    200
  • #DaysOfCode 第七周回顾

    #100DaysOfCode第七周:Go语言进阶与LeetCode刷题 本周是#100DaysOfCode学习计划中的一个重要里程碑。我深入学习了Go语言,巩固了对高级概念的理解,并坚持在LeetCode上练习算法题。以下是本周的学习成果:…

    2025年2月28日
    200
  • 我讨厌 gRPC,直到这个工具开始简化它!

    grpc:google 高性能 rpc 框架的简易上手指南 gRPC,Google 的开源远程过程调用 (RPC) 框架,以其构建高性能、高效 API 的能力而备受青睐,尤其适用于微服务架构。然而,它的初始设置过程复杂,常常让开发者望而却步…

    2025年2月28日
    200
  • Ore:Go 的高级依赖注入包

    Ore:Go 语言的高级依赖注入库 项目文档 | GitHub 代码库 Go 语言以其简洁性和高性能而闻名,但在依赖管理方面,开发者常常面临挑战。虽然 Go 语言不像其他语言那样内置依赖注入框架,但许多第三方库提供了有效的解决方案。ore …

    2025年2月28日
    200
  • Go 中的编译时断言 (Golang)

    Go 语言的编译时断言并非语言内置特性,但可巧妙运用语言特性模拟实现。编译时断言用于在编译阶段而非运行时验证条件,不满足条件则编译失败,有助于尽早发现错误。 主要应用场景包括: 验证数据结构大小。检查常量或表达式的值。强制类型约束和其他编译…

    2025年2月28日
    200
  • tnfylink – ID 怎么样?

    大家好! 欢迎阅读关于tnfy.link系列的第二篇文章——另一个URL缩短服务!本文将深入探讨短链接生成的策略。看似简单,但选择合适的链接生成方法却充满挑战。 短链接的核心是为每个长URL创建一个短小唯一的ID。这个ID需要满足以下条件:…

    2025年2月28日
    200
  • 发现 Go:本章语言的第一步

    开启Go语言学习之旅!本文是Go语言入门系列的第一篇,将带你了解Go语言的基础知识。 Go语言的工作机制 Go是一种编译型语言。编译命令会将一个或多个.go源文件转换成机器码。 快速测试可以使用run命令直接执行程序;而对于正式程序或生产环…

    2025年2月28日
    200
  • 两指针技术

    Go语言双指针法求解最大容器面积问题 在处理数组或列表相关问题时,双指针技术是一种高效且强大的算法策略。本文将详细讲解如何利用双指针技术解决经典的“盛最多水的容器”问题,即在坐标系中找到两条垂直线,使其与x轴围成的面积最大。 问题描述 给定…

    2025年2月28日
    200
  • 使用 Go 和 Vuejs 探索 Unicode

    unicode 标准是现代计算的基石,它确保各种语言、风格甚至表情符号的文本表示和操作保持一致。本文将深入探讨 unicode 标准,并通过一个 golang 后端和 vue.js 前端构建的项目,演示如何高效地利用 unicode 进行文…

    2025年2月28日
    200
  • 什么是协程?

    Go 语言协程详解 Go 语言的协程 (goroutine) 是一种轻量级线程,用于实现并发编程,允许同时运行多个任务。 协程特性: 轻量级: 协程比传统线程占用更少的内存资源。Go 运行时可以高效地管理大量的协程,无需为每个协程创建独立的…

    2025年2月28日
    200

发表回复

登录后才能评论