Question

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?

Was it helpful?

Solution

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/

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top