iota Golang 中優雅的常量

2022-07-03 21:00:15 字數 4511 閱讀 7662

閱讀約 11 分鐘

有些概念有名字,並且有時候我們關注這些名字,甚至(特別)是在我們**中。

const (

ccvisa = "visa"

ccmastercard = "mastercard"

ccamericanexpress = "american express"

)

在其他時候,我們僅僅關注能把乙個東西與其他的做區分。有些時候,有些時候一件事沒有本質上的意義。比如,我們在乙個資料庫表中儲存產品,我們可能不想以 string 儲存他們的分類。我們不關注這個分類是怎樣命名的,此外,該名字在市場上一直在變化。

我們僅僅關注它們是怎麼彼此區分的。

const (

categorybooks = 0

categoryhealth = 1

categoryclothing = 2

)

使用 0, 1, 和 2 代替,我們也可以選擇 17, 43, 和 61。這些值是任意的。

常量是重要的,但是它們很難推斷,並且難以維護。在一些語言中像 ruby 開發者通常只是避免它們。在 go,常量有許多微妙之處。當用好了,可以使得**非常優雅且易維護的。

在 golang 中,乙個方便的習慣就是使用iota標示符,它簡化了常量用於增長數字的定義,給以上相同的值以準確的分類。

const (

categorybooks = iota // 0

categoryhealth // 1

categoryclothing // 2

)

自增長常量經常包含乙個自定義型別,允許你依靠編譯器。

type stereotype int

const (

typicalnoob stereotype = iota // 0

typicalhipster // 1

typicalunixwizard // 2

typicalstartupfounder // 3

)

如果乙個函式以int作為它的引數而不是stereotype,如果你給它傳遞乙個stereotype,它將在編譯器期出現問題。

func countallthethings(i int) string 

func main()

// output:

// cannot use typicalhipster (type stereotype) as type int in argument to countallthethings

相反亦是成立的。給乙個函式以stereotype作為引數,你不能給它傳遞int

func sosayeththe(character stereotype) string 

return s

}func main()

// output:

// cannot use i (type int) as type stereotype in argument to sosayeththe

這是乙個戲劇性的轉折,儘管如此。你可以傳遞乙個數值常量,然後它能工作。

func main() 

// output:

// i'm a confused ninja rockstar.

這是因為常量在 go 中是弱型別直到它使用在乙個嚴格的上下文環境中。

設想你在處理消費者的音訊輸出。音訊可能無論什麼都沒有任何輸出,或者它可能是單聲道,立體聲,或是環繞立體聲的。

這可能有些潛在的邏輯定義沒有任何輸出為 0,單聲道為 1,立體聲為 2,值是由通道的數量提供。

所以你給 dolby 5.1 環繞立體聲什麼值。

一方面,它有6個通道輸出,但是另一方面,僅僅 5 個通道是全頻寬通道(因此 5.1 稱號 - 其中.1表示的是低頻效果通道)。

不管怎樣,我們不想簡單的增加到 3。

我們可以使用下劃線跳過不想要的值。

type audiooutput int

const (

outmute audiooutput = iota // 0

outmono // 1

outstereo // 2__

outsurround // 5

)

iota可以做更多事情,而不僅僅是 increment。更精確地說,iota總是用於 increment,但是它可以用於表示式,在常量中的儲存結果值。

這裡我們建立乙個常量用於位掩碼。

type allergen int

const (

igeggs allergen =1 << iota //1 <<0 which is 00000001

igchocolate //1 <<1 which is 00000010

ignuts //1 <<2 which is 00000100

igstrawberries //1 <<3 which is 00001000

igshellfish //1 <<4 which is 00010000

)

這個工作是因為當你在乙個const組中僅僅有乙個標示符在一行的時候,它將使用增長的iota取得前面的表示式並且再運用它,。在 go 語言的 spec 中, 這就是所謂的隱性重複最後乙個非空的表示式列表。

如果你對雞蛋,巧克力和海鮮過敏,把這些 bits 翻轉到 「on」 的位置(從左到右對映 bits)。然後你將得到乙個 bit 值00010011,它對應十進位制的 19。

fmt.println(igeggs | igchocolate | igshellfish)

// output:

// 19

這是在 effective go 中乙個非常好定義數量級的示例:

type bytesize float64

const (

_ = iota // ignore first value by assigning to blank identifier

kb bytesize = 1 << (10 * iota) // 1 << (10*1)

mb // 1 << (10*2)

gb // 1 << (10*3)

tb // 1 << (10*4)

pb // 1 << (10*5)

eb // 1 << (10*6)

zb // 1 << (10*7)

yb // 1 << (10*8)

)

今天我學習到了在 zettabyte 之後是 yottabyte。

當你在把兩個常量定義在一行的時候會發生什麼?

banana 的值是什麼? 2 還是 3? durian 的值又是?

const (

cherimoya, durian

elderberry, fig

)

iota在下一行增長,而不是立即取得它的引用。

// banana: 2

// cherimoya: 2

// durian: 3

// elderberry: 3

// fig: 4

這搞砸了,因為現在你的常量有相同的值。

因此,對的

在 go 中,關於常量有很多東西可以說,你應該在 golang 部落格讀讀 rob pike 的這篇文章。

TCP中的優雅關閉和非優雅關閉

優雅關閉 其實就是正常的四次揮手 非優雅關閉 向對端傳送乙個rst報文直接進入closed狀態 伺服器為了避免太多time wait的關閉方式 1.保證由客戶端主動發起關閉 2.關閉的時候使用rst的方式 3.對處於time wait狀態的tcp允許重用 一般我們當然最好是選擇第一種方式,實在沒有辦...

golang中的優雅中止

不過,業務中 總會存在對中止比較敏感的介面 比如支付相關 並且 總會存在一些帶狀態的服務,此時優雅中止就顯得比較重要了。本文通過乙個go 定時任務示例來簡單介紹 go 技術棧中優雅中止的處理思路。作為高可靠的服務平台,k8s 定義了終止 pod 業務程序在 pod 中執行 的基本步驟 當主動刪除 p...

C 中的常成員和常物件函式

1 建立物件時新增const關鍵字,這個物件就不可再修改,就有了常屬性,就意味著整個物件中的所有東西都不能修改。我們知道被const修飾的物件一旦被初始化了就不可改變,來看乙個例子 include include using namespace std class dog void show obj...