You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Go allows the static type of a newly declared-and-defined variable to be inferred from
the expression initializing the variable using the ":=" operator, as in
a := 4 // Now "a" has type "int"
b := a // "b" also has type "int"
However, it is otherwise impossible to declare the static type of a variable, array
entry, or map key or value without hardcoding its type. Specifically, as described in
this Stack Overflow post
(http://stackoverflow.com/questions/14191043/get-static-type-of-struct-element/14191310#14191310),
I was writing a tool that determines the combined size of all the files under a
directory, like the `du -s` command, that remembers the inodes that it has visited so
that hard-linked files don't have their sizes counted twice. I intended to keep track of
the inodes using a map from the type of syscall.Stat_t.Ino (which is uint64) to a struct
defined as
type ino_entry struct {
st *syscall.Stat_t
nodes []string
}
where `nodes` contains the names of all the files hard-linked to the inode.
However, to make this map, it's required to hardcode the type of syscall.Stat_t.Ino into
the declaration of the map, as in
make(map [uint64] ino_entry)
whereas it might be useful to be able to declare this as
make(map [typeof(syscall.Stat_t.Ino)] ino_entry)
where `typeof` would obtain the static type of a variable, struct member, or interface
member (I'm not so sure that this would be useful, since only functions may be declared
as parts of interfaces).
With this change, the following declarations would all become legal (given that `st` is
a variable of type `*syscall.Stat_t`):
entmap := make(map [typeof(syscall.Stat_t.Ino)] ino_entry) // Works on elements of a struct type
var ino1 typeof(st.Ino) // as well as elements of a struct variable
ino1 = 0
inoa := []typeof(ino1){0, 1, 2}
inop := new(typeof(ino1))
ino2 := *inop // ino2 == ino
for i, ino := range inoa {
fmt.Printf("inoa[%v] = %v\n", i, ino) // prints inoa[0] = 0, etc.
}
// We can assign to maps too
for i := 0; i != len(inoa); i++ {
entp := new(ino_entry)
entmap[inoa[i]] = *entp
}
In general, any function that today takes an argument of generic type (i.e., type T)
could obtain that type from typeof() as well.
Right now, as far as I can tell, the only way to avoid hardcoding the type in these
situations is to use reflection, whereas all of the above could be done statically. One
wrinkle that I can see is that it might be useful to access the static type of the keys
and values of a map, or that of the elements of an array or slice, separately from the
type of the map or slice as a whole, whereas there's no syntax for that right now in the
general case (although it's possible if you already have an index into the slice or map
using `typeof(my_slice[idx])`, `typeof(key)`, and `typeof(my_map[key])`). Also, the
syntax for this is just a suggestion, although I avoided `x.(type)` since that's already
associated with switching on the type of an interface.
The text was updated successfully, but these errors were encountered:
Go supports type inference based on the type of a value, but only where a value must
occur - in a variable initializer of a variable _declaration_. (`v := expr` === `var v T
= expr`, where T is type of `expr`). Struct fields don't allow initializing expressions
in the declaration. Seeing a name of a type field where a type lit or type name normaly
is, would be IMO strange.
If some kind of referring to a type by naming some existing entity should be adopted,
them IMO it have to be available everywhere, not only for struct fields.
Anyway, IMO this feature request, if adopted, makes more harm to the language than what
value it brings.
Is there a precedence in any other statically typed language providing something like
this? (Not a decision factor, would like to take a look on it)
by RIrelan:
The text was updated successfully, but these errors were encountered: