获取结构元素的静态类型

huangapple go评论121阅读模式
英文:

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。在上面讨论的短变量声明的情况下,TU无法推断

英文:

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.

huangapple
  • 本文由 发表于 2013年1月7日 14:35:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/14191043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定