首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用iota枚举字符串常量

用iota枚举字符串常量
EN

Stack Overflow用户
提问于 2018-09-06 16:18:57
回答 2查看 1.7K关注 0票数 1

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

代码语言:javascript
复制
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"

以下内容不起作用:

代码语言:javascript
复制
FirstPort = string(iota + 3333)

也没有

代码语言:javascript
复制
FirstPort = fmt.Sprintf("%d", iota + 3333)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-06 16:37:28

引用规格: Iota:

常量申报中,预先声明的标识符iota表示连续的非类型化整数常量

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

不幸的是,从整数到string的简单类型的string不会产生数值的基-10表示,但是:

将有符号或无符号整数值转换为字符串类型将产生包含整数的UTF-8表示形式的字符串。

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

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

,但仍然有一个解决方案.

我不认为这是值得的麻烦和可读性的损失,但实际上,您可以定义string常量保持不断增加的十进制数使用iota

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

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

  • 数字的最后一个数字(以基数10表示)是i % 10
  • 前面的数字是i / 10 % 10
  • 前面那个是i / 100 % 10
  • 等等..。

为了获得一个数字的rune (在0..9的范围内),我们可以简单地将'0'添加到其中,并将其转换为string。仅此而已。

这就是我们如何将它编码为一个1位的字符串数:

代码语言:javascript
复制
n0 = string('0'+iota%10)

对于2位数的数字:

代码语言:javascript
复制
n00 = string('0'+iota/10%10) + string('0'+iota/1%10)

对于三位数的数字:

代码语言:javascript
复制
n000 = string('0'+iota/100%10) + string('0'+iota/10%10) + string('0'+iota/1%10)

让我们看看它的作用:

代码语言:javascript
复制
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
)

打印结果:

代码语言:javascript
复制
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)

输出(在围棋游乐场上尝试):

代码语言:javascript
复制
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20

到目前为止还不错,但是我们如何从3333开始呢?

也不是一个问题,可以很容易实现。我们可以移动iota,只需在其中添加一个“初始”数字。这就够了。

让我们看看第一个数字将是3339的例子

代码语言:javascript
复制
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)
}

上面的输出是预期的(在围棋游乐场上尝试一下):

代码语言:javascript
复制
3339
3340
3341
票数 6
EN

Stack Overflow用户

发布于 2018-09-06 16:31:46

您正在创建非类型化数字常量。当有疑问时,检查规格。要创建具有主机和端口号的字符串,只需使用fmt.Sprintf,如下所示:

代码语言:javascript
复制
package main

const (
    FirstPort = iota+3333
    SecondPort
    ThirdPort
)

func main() {
    hostPort := fmt.Sprintf("localhost:%d", FirstPort)
    fmt.Println(hostPort)
}

这就是它的全部:演示

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52208395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档