用iota枚举字符串常量 [英] Enumerating string constants with iota
问题描述
以下示例使用iota定义了一系列从3333开始的端口号.
The following example defines a series of port numbers starting at 3333 using iota.
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"
?
When combining hostname and ports, I'd like to avoid having to wrap the port constant in fmt.Sprint
and simply write, for example, "localhost:"+SecondPort
. Is there a way to use iota to define the port numbers as string constants, e.g "3334"
?
以下内容无效:
FirstPort = string(iota + 3333)
也不是
FirstPort = fmt.Sprintf("%d", iota + 3333)
推荐答案
引用自规格:Iota:
Within a constant declaration, the predeclared identifier
iota
represents successive untyped integer constants.
所以 iota
为您提供了整数常量.如果需要 string
常量,我们需要找到一种将整数转换为以10为底的 string
表示形式的方法.这种方式必须是常量表达式,否则我们不能在常量声明中使用它.
So iota
provides you integer constants. If we want string
constants, we need to find a way to convert an integer to its base-10 string
representation. This way must be a constant expression, else we can't use it in a constant declaration.
对于我们来说,很不幸,一个简单的类型转换从整数到 string
不会产生以10为底的数值表示形式,但是:
Unfortunately for us, a simple type conversion from integer to string
will not yield the base-10 representation of the numerical value, but:
将有符号或无符号整数值转换为字符串类型会产生一个包含整数的UTF-8表示形式的字符串.
Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer.
因此结果将是一个包含单个符文的 string
,该符文的值(Unicode代码点)是源编号.
So the result will be a string
holding a single rune, whose value (the Unicode codepoint) is the source number.
还调用转换器"功能,例如 strconv.Itoa()
或 fmt.Sprint()
退出这个问题,因为调用这些函数不能是常量表达式的一部分,所以结果只能在变量声明中使用(更不用说我们不能使用 iota
,它只能在常量中使用声明).
Also calling "converter" functions such as strconv.Itoa()
or fmt.Sprint()
is out of the question, as calling those functions cannot be part of a constant expression, so the result could only be used in a variable declaration (not to mention we couldn't use iota
, it's only allowed in constant declarations).
但是仍然有解决方案.
我认为这不值得花心思,也不值得失去可读性,但是实际上,您可以使用 iota <定义不断增加的十进制数字的
/code>. string
常量
I don't think it is worth the hassle and the loss of readability, but actually you can define string
constants holding increasing decimal numbers using iota
.
该解决方案从数字中构建完整"数字.我们可以通过将数字的数字(作为 string
表示形式.
The solution builds the "complete" numbers from digits. We can obtain the base-10 string
representation by concatenating the digits (as string
values) of the number.
要解决的最后一个问题是如何列出"数字.这是简单的算法:
Last question to solve for this is how to "list" the digits of a number. This is simple arithmetic:
- 数字的最后一位数字(以10为底)是
i%10
. - 前面的数字是
i/10%10
. - 之前的那个是
i/100%10
. - 依此类推...
并且要获得数字的 rune
(在 0..9
的范围内),我们可以简单地添加'0'
并将其转换为 string
.就是这样.
And to obtain the rune
for a digit (which is in the range of 0..9
), we can simply add '0'
to it, and convert it to string
. And that's all.
这是我们如何为1位数字的字符串号进行编码的方式:
This is how we can code this for a 1-digit string number:
n0 = string('0'+iota%10)
对于两位数的数字:
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)
输出(在游乐场上尝试):
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
到目前为止还不错,但是我们如何使它从 3333
开始?
So far so good, but how do we make it start at 3333
?
这也不是问题,可以轻松实现.我们可以通过简单地在iota上添加一个初始"数字来移位.这就是全部.
Also not a problem, can be achieved easily. We can shift the iota, simply by adding an "initial" number to it. And that's all it takes.
让我们看一个示例,其中第一个数字为 3339
:
Let's see an example where the first number will be 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)
}
上述内容的输出是预期的(请在游乐场上尝试):
Output of the above is the expected (try it on the Go Playground):
3339
3340
3341
这篇关于用iota枚举字符串常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!