请教大佬,Golang Go语言中如何根据变量名获取该变量的数据

发布于 1周前 作者 bupafengyu 来自 Go语言

请教大佬,Golang Go语言中如何根据变量名获取该变量的数据

比如有

const (
    A iota
    B
    C
    D
)

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

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

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

12 回复

key, value := range a ?

更多关于请教大佬,Golang Go语言中如何根据变量名获取该变量的数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这种变量名对应不到的吧,编译后或许变量名就没了,可以试试用 struct 给成员变量打 tag,然后用 reflect 包反射 struct

如果是想要把 A-Z 映射到 0-25,可以类似这样 ‘D’-‘A’ -> 3

你是不是在想 eval ?

具体问题是,有 A - F 个权限,存库里的时候,为了后台方便查看,存的都是字符串’A’ … ‘F’. 但是在实际用的使用,为了可以&& , 只能用 0 2 4 8 这种数字。现在的实现是使用 map,list,一个用来存 key value,一个用来做排序 然后代码越看越臭了

你这个场景键不多,遍历一下 list 就可以了

直觉是拿不到。
const 常量,在编译后直接是字面量,无法获取到它的地址,因此无法通过反射拿到了。

map 倒是可以实现。

可以用 stringer 自动生成,举个例子

安装 stringer

shell<br>go get -u -a <a target="_blank" href="http://golang.org/x/tools/cmd/stringer" rel="nofollow noopener">golang.org/x/tools/cmd/stringer</a><br>

permission.go

golang<br>package core<br><br>import (<br> "sort"<br> "strings"<br>)<br><br>//go:generate stringer --type Permission<br><br>type Permission int<br><br>const (<br> A Permission = iota<br> B<br> C<br> D<br> E<br> F<br>)<br><br>func PermissionFromName(p string) (Permission, bool) {<br> idx := strings.Index(_Permission_name, p)<br> if idx &lt; 0 {<br> return 0, false<br> }<br><br> pos := sort.Search(len(_Permission_index), func(i int) bool {<br> return _Permission_index[i] &gt;= uint8(idx)<br> })<br><br> return Permission(pos), true<br>}<br>

执行 go generate

shell<br>go generate ./...<br>

生成 permission_string.go 文件

golang<br>// Code generated by "stringer --type Permission"; DO NOT EDIT.<br><br>package core<br><br>import "strconv"<br><br>func _() {<br> // An "invalid array index" compiler error signifies that the constant values have changed.<br> // Re-run the stringer command to generate them again.<br> var x [1]struct{}<br> _ = x[A-0]<br> _ = x[B-1]<br> _ = x[C-2]<br> _ = x[D-3]<br> _ = x[E-4]<br> _ = x[F-5]<br>}<br><br>const _Permission_name = "ABCDEF"<br><br>var _Permission_index = [...]uint8{0, 1, 2, 3, 4, 5, 6}<br><br>func (i Permission) String() string {<br> if i &lt; 0 || i &gt;= Permission(len(_Permission_index)-1) {<br> return "Permission(" + strconv.FormatInt(int64(i), 10) + ")"<br> }<br> return _Permission_name[_Permission_index[i]:_Permission_index[i+1]]<br>}<br>

最后,可以使用 Permission.String() 方法将 enum 转成 string,也可以用 PermissionFromName() 转回来。enum 有变动的时候,重新执行一下 go generate 重新生成代码即可。

不知道为啥 md 格式没生效啊

感谢各位老哥了,这样看还是我的 map array 好用。。。。

在Go语言中,直接通过变量名获取变量数据是不可能的,因为Go是静态类型语言,编译期就确定了变量的类型和内存布局,不支持运行时反射变量名到变量的映射。不过,你可以通过其他方式间接实现类似功能,比如使用结构体和映射(map)。

一种常见方法是使用map,将变量名作为字符串键,变量值作为值存储。例如:

package main

import "fmt"

func main() {
    data := make(map[string]interface{})
    data["var1"] = 42
    data["var2"] = "hello"
    
    // 根据变量名获取数据
    if value, ok := data["var1"]; ok {
        fmt.Println("var1:", value)
    } else {
        fmt.Println("var1 not found")
    }
    
    if value, ok := data["var2"]; ok {
        fmt.Println("var2:", value)
    } else {
        fmt.Println("var2 not found")
    }
}

这样,你可以通过字符串键(模拟变量名)来获取相应的值。不过需要注意的是,这种方式失去了类型安全,因为所有值都存储为interface{}类型,需要在使用时进行类型断言。

如果你的需求更复杂,可能需要考虑使用反射(reflect包)来操作结构体字段,但这仍然需要你有一个结构体实例,而不是直接通过变量名操作。反射通常用于库和框架开发,日常编码中应谨慎使用,因为它可能降低代码的可读性和性能。

回到顶部