gpt4 book ai didi

string - 用 iota 枚举字符串常量

转载 作者:IT王子 更新时间:2023-10-29 01:51:56 26 4
gpt4 key购买 nike

以下示例使用 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)

最佳答案

引自Spec: Iota:

Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants.

因此 iota 为您提供整数常量。如果我们想要 string 常量,我们需要找到一种方法将整数转换为其以 10 为底的 string 表示形式。这种方式必须是 constant expression , 否则我们不能在常量声明中使用它。

对我们来说不幸的是,一个简单的类型 conversion从整数到 string 不会产生数值的 base-10 表示,但是:

Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer.

因此结果将是一个包含单个 rune 的字符串,其值(Unicode 代码点)是源编号。

同时调用“转换器”功能,例如 strconv.Itoa()fmt.Sprint()是不可能的,因为调用这些函数不能是常量表达式的一部分,所以结果只能用于变量声明(更不用说我们不能使用 iota,它只允许在常量声明中)。

但还是有办法的。

我认为这不值得麻烦和可读性的损失,但实际上你可以定义 string 常量 使用 iota.

该解决方案从数字构建“完整”数字。我们可以通过连接数字的数字(作为 string 值)来获得以 10 为底的 string 表示。

要解决的最后一个问题是如何“列出”数字的数字。这是简单的算术:

  • 数字的最后一位(以 10 为基数)是 i % 10
  • 前面的数字是i/10 % 10
  • 之前的那个是i/100 % 10
  • 等等...

要获得一个数字(在0..9范围内)的rune,我们可以简单地添加'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

关于string - 用 iota 枚举字符串常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52208395/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com