"_ struct{}" ? What does it mean?

1,949 views
Skip to first unread message

oju...@gmail.com

unread,
Sep 2, 2015, 5:11:49 PM9/2/15
to golang-nuts
At
 
we have:
 
type ProgInfo struct {
 Flags    uint32   // flag bits
 Reguse   uint64   // registers implicitly used by this instruction
 Regset   uint64   // registers implicitly set by this instruction
 Regindex uint64   // registers used by addressing mode
 _        struct{} // to prevent unkeyed literals
}
 
Could someone explain to me what that "_ struct{}" does? I don't know that idiom. What is it for?

Chris Manghane

unread,
Sep 2, 2015, 5:34:30 PM9/2/15
to oju...@gmail.com, golang-nuts
In this struct, it is a field identified by the blank identifier with a type size of 0 (the size of an empty struct type). Because the field is the blank identifier, it cannot be accessed directly; it only serves as a placeholder. A consequence of this is, as the comment states, unkeyed literals of ProgInfo cannot be constructued e.g. ProgInfo{1, 2, 3, 4} must be ProgInfo{Flags: 1, Reguse: 2, Regset: 3, Regindex: 4} or the compiler will complain that there is a missing field in the struct literal. I'd imagine this is done to avoid bugs that might arise from specifying the arguments in an incorrect order.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Steven Blenkinsop

unread,
Sep 2, 2015, 5:39:24 PM9/2/15
to Chris Manghane, oju...@gmail.com, golang-nuts
Or to allow fields to be added in the future.

oju...@gmail.com

unread,
Sep 2, 2015, 5:51:40 PM9/2/15
to golang-nuts, oju...@gmail.com
Nice! Thanks.

Jacob Hands

unread,
Sep 2, 2015, 7:08:20 PM9/2/15
to golang-nuts, oju...@gmail.com
Is this a good/common practice?

Steven Blenkinsop

unread,
Sep 3, 2015, 12:33:49 PM9/3/15
to Jacob Hands, golang-nuts, oju...@gmail.com
The standard library simply doesn't promise that the use of unkeyed literals with library types will remain compatible, rather than using a trick like this to enforce the use of keyed literals. So, I wouldn't consider it a recommended practice. On the other hand, it won't interfere with good practice in any way either.

--

Roberto Zanotto

unread,
Sep 3, 2015, 12:47:31 PM9/3/15
to golang-nuts, oju...@gmail.com
Not so common I believe, but not a bad practice either. It is useful for *some* struct if you know there is a chance that other fields will be added later. There is also this https://github.com/golang/go/issues/2794

minux

unread,
Sep 5, 2015, 9:37:50 PM9/5/15
to golang-nuts
On Wed, Sep 2, 2015 at 5:33 PM, 'Chris Manghane' via golang-nuts <golan...@googlegroups.com> wrote:
In this struct, it is a field identified by the blank identifier with a type size of 0 (the size of an empty struct type). Because the field is the blank identifier, it cannot be accessed directly; it only serves as a placeholder. A consequence of this is, as the comment states, unkeyed literals of ProgInfo cannot be constructued e.g. ProgInfo{1, 2, 3, 4} must be ProgInfo{Flags: 1, Reguse: 2, Regset: 3, Regindex: 4} or the compiler will complain that there is a missing field in the struct literal. I'd imagine this is done to avoid bugs that might arise from specifying the arguments in an incorrect order.

Actually it is done to help the conversion from unkeyed literals to
keyed literals and let the compiler catch all the unconverted literals.

I wouldn't consider it a good/common practice. It's a trick, but I don't
think it's usually required to go to this length to forbid unkeyed literals
(the compiler will catch unkeyed literal not initializing all fields, so
adding fields will definitely be caught at compile time even without
this trick.)
Reply all
Reply to author
Forward
0 new messages