亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

用 iota 枚舉字符串常量

用 iota 枚舉字符串常量

Go
aluckdog 2023-03-29 17:17:21
以下示例使用 iota 定義了一系列從 3333 開始的端口號。package mainimport (    "fmt")const (FirstPort = iota+3333SecondPortThirdPort)func main() {    hostAndPort := "localhost:"+fmt.Sprint(SecondPort)    fmt.Printf("%s", hostAndPort )     // Output:    // localhost:3334}組合主機名和端口時,我想避免必須將端口常量包裝在其中fmt.Sprint并簡單地編寫,例如,"localhost:"+SecondPort。有沒有辦法使用 iota 將端口號定義為字符串常量,例如"3334"?以下不起作用:FirstPort = string(iota + 3333)也沒有FirstPort = fmt.Sprintf("%d", iota + 3333)
查看完整描述

2 回答

?
慕容森

TA貢獻1853條經驗 獲得超18個贊

引用自規范:Iota:

在常量聲明中,預先聲明的標識符iota表示連續的無類型整數常量。

所以iota為您提供整數常量。如果我們想要string常量,我們需要找到一種方法將整數轉換為其以 10 為底的string表示形式。這種方式必須是一個常量表達式,否則我們不能在常量聲明中使用它。

對我們來說不幸的是,從整數到的簡單類型轉換string不會產生數值的以 10 為底的表示形式,但是:

將有符號或無符號整數值轉換為字符串類型會生成一個包含整數的 UTF-8 表示形式的字符串。

所以結果將是一個string持有單個符文,其值(Unicode 代碼點)是源編號。

也不能調用諸如strconv.Itoa()orfmt.Sprint()之類的“轉換器”函數,因為調用這些函數不能成為常量表達式的一部分,因此結果只能用于變量聲明(更不用說我們不能使用 ,它iota只是常量聲明中允許)。

但是還是有辦法解決的。

我認為這不值得麻煩和可讀性的損失,但實際上你string可以使用iota.

該解決方案從數字構建“完整”數字。string我們可以通過連接數字的數字(作為值)來獲得以 10 為底的表示形式string。

最后要解決的問題是如何“列出”數字的數字。這是簡單的算術:

  • 數字的最后一位(以 10 為基數)是i % 10.

  • 前面的數字是i / 10 % 10。

  • 之前的那個是i / 100 % 10。

  • 等等...

要獲得rune一個數字(在 的范圍內0..9),我們可以簡單地'0'對其進行加法,并將其轉換為string.?就這樣。

這就是我們如何將其編碼為 1 位字符串數字:

n0?=?string('0'+iota%10)

對于 2 位數字:

n00?=?string('0'+iota/10%10)?+?string('0'+iota/1%10)

對于 3 位數字:

n000?=?string('0'+iota/100%10)?+?string('0'+iota/10%10)?+?string('0'+iota/1%10)

讓我們看看它的實際效果:

const (

? ? P00 = string('0'+iota/10%10) + string('0'+iota/1%10)

? ? P01

? ? P02

? ? P03

? ? P04

? ? P05

? ? P06

? ? P07

? ? P08

? ? P09

? ? P10

? ? P11

? ? P12

? ? P13

? ? P14

? ? P15

? ? P16

? ? P17

? ? P18

? ? P19

? ? P20

)

打印結果:


fmt.Printf("%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n%v\n",

? ? P00, P01, P02, P03, P04, P05, P06, P07, P08, P09,

? ? P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)

輸出(在Go Playground上嘗試):


00

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

到目前為止一切順利,但我們如何讓它從 開始3333?


也不是問題,可以輕松實現。我們可以簡單地通過向它添加一個“初始”數字來移動iota。這就是它所需要的。


讓我們看一個例子,其中第一個數字是3339:


const (

? ? P3339 = string('0'+(iota+3339)/1000%10) +

? ? ? ? string('0'+(iota+3339)/100%10) +

? ? ? ? string('0'+(iota+3339)/10%10) +

? ? ? ? string('0'+(iota+3339)/1%10)

? ? P3340

? ? P3341

)


func main() {

? ? fmt.Println(P3339)

? ? fmt.Println(P3340)

? ? fmt.Println(P3341)

}

上面的輸出是預期的(在Go Playground上試試):


3339

3340

3341


查看完整回答
反對 回復 2023-03-29
?
慕雪6442864

TA貢獻1812條經驗 獲得超5個贊

您正在創建無類型的數字常量。要創建帶有主機和端口號的字符串,您可以fmt.Sprintf像這樣簡單地使用:


package main


const (

? ? FirstPort = iota+3333

? ? SecondPort

? ? ThirdPort

)


func main() {

? ? hostPort := fmt.Sprintf("localhost:%d", FirstPort)

? ? fmt.Println(hostPort)

}


查看完整回答
反對 回復 2023-03-29
  • 2 回答
  • 0 關注
  • 140 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號