用 iota 枚举字符串常量

以下示例使用 iota 定义了一系列从 3333 开始的端口号。


package main


import (

    "fmt"

)

const (

FirstPort = iota+3333

SecondPort

ThirdPort

)

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)


aluckdog
浏览 109回答 2
2回答

慕容森

引用自规范: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上尝试):000102030405060708091011121314151617181920到目前为止一切顺利,但我们如何让它从 开始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上试试):333933403341

慕雪6442864

您正在创建无类型的数字常量。要创建带有主机和端口号的字符串,您可以fmt.Sprintf像这样简单地使用:package mainconst (    FirstPort = iota+3333    SecondPort    ThirdPort)func main() {    hostPort := fmt.Sprintf("localhost:%d", FirstPort)    fmt.Println(hostPort)}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go