以下示例使用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)
答案 0 :(得分:4)
在constant declaration中,预定义的标识符
iota
表示连续的无类型整数constants。
因此iota
为您提供了整数常量。如果我们需要string
常量,我们需要找到一种方法将整数转换为以10为底的string
表示形式。这种方式必须是constant expression,否则我们不能在常量声明中使用它。
不幸的是,从整数到string
的简单类型conversion不会产生以10为底的数值表示,但是:
将有符号或无符号整数值转换为字符串类型会产生一个包含整数的UTF-8表示形式的字符串。
因此,结果将是string
,其中包含单个符文,其值(Unicode代码点)是源编号。
也无法调用strconv.Itoa()
或fmt.Sprint()
之类的“转换器”函数,因为调用这些函数不能是常量表达式的一部分,因此结果只能在变量中使用声明(更不用说我们不能使用iota
,它只在常量声明中允许)。
但是仍然有解决方案。
我认为这不值得麻烦和可读性的损失,但是实际上您可以使用string
来定义iota
常量并使用递增的十进制数。 >
该解决方案从数字中构建“完整”数字。通过将数字的数字(作为string
的值)进行串联,可以获得以10为底的string
表示形式。
要解决的最后一个问题是如何“列出”数字。这是简单的算法:
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
答案 1 :(得分:1)