日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
Go1.18新特性:引入新的Netip網絡庫

寫這篇文章時是大年初一,原本想說這個月就要發(fā)布 Go1.18 了。但是,好家伙,Go1.18 beta2 發(fā)布了,官方告知社區(qū) Go1.18 要拖更到 3 月份了,咕咕咕...

按需定制開發(fā)可以根據自己的需求進行定制,網站制作、成都網站制作構思過程中功能建設理應排到主要部位公司網站制作、成都網站制作的運用實際效果公司網站制作網站建立與制做的實際意義

如下圖:

所以還是得繼續(xù)學習新特性,今天煎魚將結合 Brad Fitzpatrick 寫的《netaddr.IP: a new IP address type for Go[1]》帶大家了解 Go1.18 的新網絡庫 net/netip 的緣由。

背景

大佬離職

原本 Go 開發(fā)團隊中的 Brad Fitzpatrick,在 2010~2020 年都在 Go 團隊工作,在 2021 年起換公司了。

如下推特的消息:

離職的原因是:做了同樣的東西太久了,有些厭煩,不想陷在一個舒適的困境中。

現(xiàn)在來看是換到了 Tailscale,做 WireGuard 相關工作,要經常與網絡庫打交道。

需求誕生

大佬公司寫的 Tailscale,本質上是一個網絡應用程序,要與網絡打交道,又是用 Go 寫的,就會涉及到標準庫 net:

  • 在單個 IP 類型上使用 net.IP。
  • 網絡表示上使用 net.IPNet。

示例代碼:

import (
"fmt"
"net"
)

func main() {
fmt.Println(net.IPv4(8, 8, 8, 8))
}

輸出結果:

8.8.8.8

Brad Fitzpatrick 在實際編寫和使用時,發(fā)現(xiàn) net 標準庫的類型有很多問題,很不好用。

現(xiàn)在有什么問題

Brad Fitzpatrick 對于標準庫 net.IP 的問題,直接在文章中列舉了出來,論據十足。

共 7 個大問題:

  • 它是可變的。net.IP 的底層類型是 []byte,這意味著你傳遞給它的任何東西都可能改變它。
  • 它不具有可比性。因為 Go 中的 slice 不具有可比性,這意味著 net.IP 不支持 Go 的 == 運算符的對比,不能作為 map 的 key 來使用。
  • 它有兩種 IP 地址類型,要糾結用 net.IP,還是 net.IPAddr,要選擇就會很煩人。
  • 它很大。Go 的 net.IP 包含 2 個部分,分別是 24 字節(jié)的 slice header 和 4/6 字節(jié)的 IP 地址。如果是 net.IPAddr 還會包含 Zone 字段。
  • 它會在堆上分配內存。Go 的 net 包到處都是分配,把更多的工作放在了 GC 上。
  • 它不可解析。從字符串形式解析 IP 時,Go 的 IP 類型無法區(qū)分 IPv4 映射的 IPv6 地址和 IPv4 地址。
  • 它是透明類型(transparent type),net.IP的定義是:type IP []byte,是其公共API的一部分,不可更改。

Brad 也有提到有些是當年早期的設計,當時經驗不足,或是沒有考慮好。

現(xiàn)在受限于 Go1 兼容性承諾,已經無法改變了(兼容性保障的雙刃劍?)。

這是個真實版 “Eating your own dog food”,所以在 Tailscale 他又重新造了一個輪子inetaf/netaddr[2],想貢獻出來,塞進標準庫里。

未來想要的樣子

對比表格如下:

特性

老方案 net.IP

新方案

不變的

, slice

可比的

, slice

占用空間小

,28~56 字節(jié)

,固定 24 字節(jié)

不在堆上分配

支持 IPv4 和 IPv6

區(qū)分 IPv4 和 IPv6

支持 IPv6 區(qū)域

不透明的類型

與標準庫互通

????,需適配方法

想要的樣子,其實是 Brad 業(yè)務實戰(zhàn)出來的訴求,就是要支持前面提到的 7 點。

解決方案

當前的進展

實現(xiàn)的結果,也就是新方案做出來了,他就是inetaf/netaddr[3] 這個庫(當然,也不排除是結果倒推理論)。并且在 Go issues 中發(fā)起 issues 和 proposal。

https://pkg.go.dev/inet.af/netaddr

Russ Cox 發(fā)起了新提案的討論《proposal: net/netaddr: add new IP address type, netaddr package (discussion)[4]》,并被接納,進入了 Go1.18 的新特性當中。

重造過程

新的 net/netip 庫的每一個考量點,Brad 都在文章中有所詳細講解。

受限于篇幅,我們拿其中兩點來分享,有興趣的小伙伴可以閱讀原文的剖析部分。

接口類型組合

在可比較這事上,Go 的接口(interface)其實是支持比較的,也就是可以作為 map 的 key 進行 == 運算符的比較。

實現(xiàn)了如下的第一版方案,設計了新的netaddr.IP 類型:

type IP struct {
ipImpl
}

type ipImpl interface {
is4() bool
is6() bool
String() string
}

type v4Addr [4]byte
type v6Addr [16]byte
type v6AddrZone struct {
v6Addr
zone string
}

上述代碼,在 IP 結構體中增加了 ipImpl 接口,既能支持比較,還可以不對外暴露(不透明類型),且可以支持 IPv6。

新的問題在于,雖然比原生 net 小了,但還是沒達到目標,還是有在堆上分配的缺點。

免分配的 24 字節(jié)

如果繼續(xù)使用接口,是無法解決根本目標(Brad 的目標是 24 字節(jié))的。

因為接口(interface)占用 16 字節(jié),剩余 8 個字節(jié)可以用,要放如下東西:

  • 地址族(v4、v6,或兩者都不是,如:IP 的零值),至少需要 2 位。
  • IPv6 的 zone 信息。

還要能比較,顯然接口是無法實現(xiàn)的,因為地址+zone 信息算一下字節(jié)數(shù),顯示是不夠用的。

正規(guī)顯式的沒辦法,Brad 想到了用打包的方式:

type IP struct {
addr [16]byte
zoneAndFamily uint64
}

但這么做,就意味著 zoneAndFamily 字段中需要計算位數(shù),再對應的推入相應的值,但也未必太折騰了。

最終 Brad 想到了,可以使用指針的方式:

type IP struct {
addr [16]byte
zoneAndFamily *T
}

再定義 3 個對應哨位值的來應用:

var (
z0 *intern.Value // 表示零值。
z4 = new(intern.Value) // 表示 IPv4 的哨位值
z6noz = new(intern.Value) // 表示 IPv6 的哨位值(沒有 zone)。
)

這樣就可以把 IP 類型固定在 24 字節(jié)。

總結

這個網絡地址庫,一般都用的比較少。但是 Brad Fitzpatrick 在此投入了大量的精力和研究,達到了最終的目標。

除去庫的功能外,有許多技術優(yōu)化點值得我們學習和參考,有興趣深入優(yōu)化部分的,可以閱讀:https://tailscale.com/blog/netaddr-new-ip-type-for-go/[5]

本文介紹的新 net/netip 庫將會在 Go1.18 中作為新特性出現(xiàn),歡迎大家一起學習交流:)

參考資料

[1]netaddr.IP: a new IP address type for Go: https://tailscale.com/blog/netaddr-new-ip-type-for-go/

[2]inetaf/netaddr: https://github.com/inetaf/netaddr

[3]inetaf/netaddr: https://github.com/inetaf/netaddr

[4]proposal: net/netaddr: add new IP address type, netaddr package): https://github.com/golang/go/discussions/47323

[5]https://tailscale.com/blog/netaddr-new-ip-type-for-go/: https://tailscale.com/blog/netaddr-new-ip-type-for-go/#wgcfg


網站欄目:Go1.18新特性:引入新的Netip網絡庫
本文路徑:http://www.5511xx.com/article/dpoocjd.html