英文:
Get static type of struct element
问题
我在Golang文档中查找了一下,并没有找到我想要实现的示例。具体来说,我想要写一个从inode(由syscall.Stat_t.Ino
表示)到ino_entry的映射,其中inode在我的机器上的类型为uint64
。
type ino_entry struct {
st *syscall.Stat_t
nodes []string
}
其中nodes表示与inode硬链接的所有文件的名称。
然而,如果可能的话,我想避免在映射的规范中直接写入字面类型uint64
。也就是说,我希望写成map [typeof(syscall.Stat_t.Ino)] ino_entry
,其中typeof(x)
返回x
的静态(即编译时)类型,而不是写成map [uint64] ino_entry
。我尝试过map [syscall.Stat_t.Ino] ino_entry
,以及类似类型开关的写法map [syscall.Stat_t.Ino.(type)] ino_entry
,但这两种写法都是语法错误。不用说,map [reflect.Typeof(syscall.Stat_t.Ino)] ino_entry
也不起作用。据我所知,实现这个功能的唯一方法是使用inomap := make(map [interface{}] ino_entry)
,然后使用类型断言来访问元素(我不知道正确的语法是什么)。
有没有一种方法可以根据另一个变量、结构体或接口成员的静态类型来声明变量的类型,而不是显式地硬编码该类型?
英文:
I've looked in the Golang documentation and haven't seen an example of how to achieve what I'm looking to do. Specifically, I'm trying to write a map from inodes, represented by syscall.Stat_t.Ino
, which has type uint64
on my machine, to ino_entry, defined as
type ino_entry struct {
st *syscall.Stat_t
nodes []string
}
where nodes represents the names of all the files hard linked to the inode.
However, I want to avoid putting the literal type uint64
in the specification of the map if I can. That is, instead of writing map [uint64] ino_entry
, I'd prefer to write map [typeof(syscall.Stat_t.Ino)] ino_entry
, where typeof(x)
returns the static (i.e., compile-time) type of x
. I've tried map [syscall.Stat_t.Ino] ino_entry
and, by analogy with type switches, map [syscall.Stat_t.Ino.(type)] ino_entry
, but both of these are syntax errors. Needless to say, map [reflect.Typeof(syscall.Stat_t.Ino)] ino_entry
doesn't work. As far as I can tell, the only way to implement this without hardcoding the type of the structure element is to use inomap := make(map [interface{}] ino_entry)
and then access the elements using type assertions (I don't know the correct syntax for this though).
Is there a way to declare the type of a variable based on the static type of another variable, or struct or interface member, without hardcoding that type explicitly?
答案1
得分: 2
看起来你正在尝试使用反射来确保机器的可移植性。如果是这样的话,有一个更好的工具可以使用。
go build
可以根据架构和操作系统进行条件文件包含的构建。
所以为每个支持的架构和操作系统组合创建一些文件。在每个文件的顶部添加一些构建约束。
例如,// +build linux,386
将导致 go 命令仅在具有 386 架构的 linux 机器上使用此文件。
然后在该文件中添加一个适合该架构的类型别名:type Ino uint64
最后,将你的映射创建为 map[Ino]ino_entry
。
通过使用类型别名和条件文件包含来实现 go 的机器可移植性。
你可以在这里阅读更多关于 go 的构建约束的信息:http://golang.org/pkg/go/build/
英文:
It looks like you are trying to use Reflection to ensure machine portability. If that is the case there is a better tool you can use.
go build
can handle conditional file inclusion for a build based on arch and os.
So create some files for each arch and os combination you support. At the top of each file add some build constraints.
// +build linux,386
for instance will cause the go command to only use this file on linux machines with a 386 arch.
Then in that file add a type alias for the type that fits that arch: type Ino uint64
Finally create your map as a map[Ino]ino_entry
.
Wala! machine portability using type aliasing and conditional file inclusion for go.
You can read more about go's build constraints here: http://golang.org/pkg/go/build/
答案2
得分: 0
Cf. OP 中的最后一个问题:是的,有一种方法可以根据任何表达式的类型来声明变量的类型,而不需要复制表达式的类型:
v := expr // 等同于 var v typeof(expr); v = expr;
expr
也包括你提到的大多数实体,例如另一个变量,一个类型为 "thing" 的结构体,但不包括接口成员(因为规范中从未提到过任何成员)。
不幸的是,这与声明映射类型无关,其中/何时使用的 类型字面量 的形式为 map[T]U
。在上面讨论的短变量声明的情况下,T
和 U
都 无法 被 推断。
英文:
Cf. the last question in the OP: Yes, there is a way how to declare a variable's type based on type of any expression, without hardcopying the expression's type:
v := expr // equal to var v typeof(expr); v = expr;
expr
also includes most of by you mentioned entities, i.e. another variable, a struct typed "thing", but not an interface member (as there are no members of anything ever mentioned in the specs).
Unfortunately, this has nothing to do with declaring a map type, where/when the type literal used is in the form map[T]U
. Here both T
and U
cannot be inferred as in the case of the short variable declaration discussed above.
答案3
得分: 0
Stat_t
对于任何机器都有相同的定义,它的Ino
字段始终是uint64
,所以这里不应该有问题。
如果有一个编译时的运算符可以静态地获取这个类型,那么它一定是被很好地隐藏起来了。
然而,你可以定义一个类型别名:type ino_id uint64
,这样对我来说更容易阅读。
英文:
Stat_t
has the same definition for any machine, and its Ino
field is always uint64
, so this shouldn't be a problem here.
If there is a compile-time operator to get this type statically, it must be well-hidden.
However, you could define a type alias: type ino_id uint64
, which looks more readable to me.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论