请教大佬, go 如何根据变量名获取该变量的数据

2020-07-23 17:57:55 +08:00
 vhysug01

比如有

const (
    A iota
    B
    C
    D
)

a := []string{"A", "B", "D"}

如何获取 a 中每个元素的值。即得到 0 1 3

之前想用 map,可是如果 cont 里是 A--Z 的话就非常麻烦了,有什么好的办法么

3597 次点击
所在节点    Go 编程语言
11 条回复
qiangmin
2020-07-23 18:00:11 +08:00
key, value := range a ?
linvon
2020-07-23 18:03:19 +08:00
这种变量名对应不到的吧,编译后或许变量名就没了,可以试试用 struct 给成员变量打 tag,然后用 reflect 包反射 struct
ll1615
2020-07-23 18:16:36 +08:00
如果是想要把 A-Z 映射到 0-25,可以类似这样 'D'-'A' -> 3
Leigg
2020-07-23 18:19:18 +08:00
你是不是在想 eval ?
vhysug01
2020-07-23 18:31:46 +08:00
具体问题是,有 A - F 个权限,存库里的时候,为了后台方便查看,存的都是字符串'A' ... 'F'. 但是在实际用的使用,为了可以&& , 只能用 0 2 4 8 这种数字。现在的实现是使用 map,list,一个用来存 key value,一个用来做排序 然后代码越看越臭了
zhujinliang
2020-07-23 18:47:28 +08:00
你这个场景键不多,遍历一下 list 就可以了
davidyanxw
2020-07-24 10:54:31 +08:00
直觉是拿不到。
const 常量,在编译后直接是字面量,无法获取到它的地址,因此无法通过反射拿到了。

map 倒是可以实现。
yiplee
2020-07-24 11:10:01 +08:00
可以用 stringer 自动生成,举个例子

安装 stringer

```shell
go get -u -a golang.org/x/tools/cmd/stringer
```

**permission.go**

```golang
package core

import (
"sort"
"strings"
)

//go:generate stringer --type Permission

type Permission int

const (
A Permission = iota
B
C
D
E
F
)

func PermissionFromName(p string) (Permission, bool) {
idx := strings.Index(_Permission_name, p)
if idx < 0 {
return 0, false
}

pos := sort.Search(len(_Permission_index), func(i int) bool {
return _Permission_index[i] >= uint8(idx)
})

return Permission(pos), true
}
```

执行 go generate

```shell
go generate ./...
```

生成 **permission_string.go** 文件

```golang
// Code generated by "stringer --type Permission"; DO NOT EDIT.

package core

import "strconv"

func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[A-0]
_ = x[B-1]
_ = x[C-2]
_ = x[D-3]
_ = x[E-4]
_ = x[F-5]
}

const _Permission_name = "ABCDEF"

var _Permission_index = [...]uint8{0, 1, 2, 3, 4, 5, 6}

func (i Permission) String() string {
if i < 0 || i >= Permission(len(_Permission_index)-1) {
return "Permission(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Permission_name[_Permission_index[i]:_Permission_index[i+1]]
}
```

最后,可以使用 Permission.String() 方法将 enum 转成 string,也可以用 PermissionFromName() 转回来。enum 有变动的时候,重新执行一下 go generate 重新生成代码即可。
yiplee
2020-07-24 11:10:36 +08:00
不知道为啥 md 格式没生效啊
yiplee
2020-07-24 11:13:51 +08:00
vhysug01
2020-07-25 16:02:47 +08:00
感谢各位老哥了,这样看还是我的 map array 好用。。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/692585

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX