问题描述
以下示例使用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:
所以 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:
因此结果将是一个包含单个符文的 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 string
常量/code>.
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 值)串联来获得以10为底的 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枚举字符串常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!