How to create a variable with needed type instead of type assertion - go

I have a function which takes an interface, like this:
func method(data interface{})
.. because I need to process different structs which have common fields/methods. In this function I use data tens or hundreds of times, in different places. It's really unpleasant to add switch a.(type) { case .. case .. all the time.
Is there a way to create a variable with just one switch with needed type and then just use this variable everywhere later? Something like:
var a .... // something here
switch data.(type) {
case *Struct1:
a = data.(*Struct1)
case *Struct2:
a = data.(*Struct2)
}
// Continue with 'a' only
a.Param = 15
fmt.Println(a.String())

Go is a statically typed language, the type of a must be known at compile time. And since Go does not support generics yet, you can't do what you want.
Try to come up with some other solution, e.g. abstract away the things you want to do with a into an interface, and have the concrete types implement that interface. Then a can be a variable of this interface type, and you can call methods of it.
If you can achieve this, actually you can even change the parameter of the data type to this interface, and no type assertion or type switch is needed.
Alternatively you could use reflection to access common fields (either for get or set) identified by their name, but reflection provides no compile-time guarantee, and it's usually less efficient. For an example how to do that, see this question: Assert interface to its type

You can't do what you ask for in your question directly, go is statically typed, so you can't have one variable that can hold different types, and still access that variable as if it is typed.
If you're only working on the common struct fields in your method, you are perhaps better off gathering all the common variables in its own struct, illustrated below as the commons struct and have your method take that type as an argument
package main
import (
"fmt"
)
type commons struct {
name string
age int
}
type structA struct {
commons
other_stuff int
}
type structB struct {
commons
foo string
}
func method(c* commons) {
fmt.Println(c)
c.age +=1
}
func main() {
a := structA{commons{"foo", 44}, 1}
b := structB{commons{"bar", 33}, "test"}
method(&a.commons)
method(&b.commons)
fmt.Println(a)
}
Go playground

I can't figure out what is your real goal but if the "method" you want to write handles common fields from similar structures, and you cannot fix original structures using Type Embedding, as #nos said above, then you can try to make another structure for method-internal use:
var v Vehicle // with common fields
switch data.(type) {
case *Car:
v.Handle = data.(*Car).Handle // or CircleHandle
case *Motorcycle:
v.Handle = data.(*Motorcycle).Handle // or BarHandle
}
v.Degree = 15
v.Speed = 50
v.Direction = "left"
v.Style = "rough"
/// so many things on `v`...
steering(v)
I think it is not a good approach but sometimes... :-)

Related

Golang wrap calls to package methods generically [duplicate]

I want to write a single function that can add certain fields to Firebase message structs. There are two different types of message, Message and MulticastMessage, which both contain Android and APNS fields of the same types, but the message types don't have an explicitly declared relationship with each other.
I thought I should be able to do this:
type firebaseMessage interface {
*messaging.Message | *messaging.MulticastMessage
}
func highPriority[T firebaseMessage](message T) T {
message.Android = &messaging.AndroidConfig{...}
....
return message
}
but it gives the error message.Android undefined (type T has no field or method Android). And I can't write switch m := message.(type) either (cannot use type switch on type parameter value message (variable of type T constrained by firebaseMessage)).
I can write switch m := any(message).(type), but I'm still not sure whether that will do what I want.
I've found a few other SO questions from people confused by unions and type constraints, but I couldn't see any answers that helped explain why this doesn't work (perhaps because I'm trying to use it with structs instead of interfaces?) or what union type constraints are actually useful for.
In Go 1.18 you cannot access common fields1, nor common methods2, of type parameters. Those features don't work simply because they are not yet available in the language. As shown in the linked threads, the common solution is to specify methods to the interface constraint.
However the the types *messaging.Message and *messaging.MulticastMessage do not have common accessor methods and are declared in a library package that is outside your control.
Solution 1: type switch
This works fine if you have a small number of types in the union.
func highPriority[T firebaseMessage](message T) T {
switch m := any(message).(type) {
case *messaging.Message:
setConfig(m.Android)
case *messaging.MulticastMessage:
setConfig(m.Android)
}
return message
}
func setConfig(cfg *messaging.AndroidConfig) {
// just assuming the config is always non-nil
*cfg = &messaging.AndroidConfig{}
}
Playground: https://go.dev/play/p/9iG0eSep6Qo
Solution 2: wrapper with method
This boils down to How to add new methods to an existing type in Go? and then adding that method to the constraint. It's still less than ideal if you have many structs, but code generation may help:
type wrappedMessage interface {
*MessageWrapper | *MultiCastMessageWrapper
SetConfig(c foo.Config)
}
type MessageWrapper struct {
messaging.Message
}
func (w *MessageWrapper) SetConfig(cfg messaging.Android) {
*w.Android = cfg
}
// same for MulticastMessageWrapper
func highPriority[T wrappedMessage](message T) T {
// now you can call this common method
message.SetConfig(messaging.Android{"some-value"})
return message
}
Playground: https://go.dev/play/p/JUHp9Fu27Yt
Solution 3: reflection
If you have many structs, you're probably better off with reflection. In this case type parameters are not strictly needed but help provide additional type safety. Note that the structs and fields must be addressable for this to work.
func highPriority[T firebaseMessage](message T) T {
cfg := &messaging.Android{}
reflect.ValueOf(message).Elem().FieldByName("Android").Set(reflect.ValueOf(cfg))
return message
}
Playground: https://go.dev/play/p/3DbIADhiWdO
Notes:
How can I define a struct field in my interface as a type constraint (type T has no field or method)?
In Go generics, how to use a common method for types in a union constraint?

Can I get a variable of a type based on reflect.Type [duplicate]

I have a function which takes an interface, like this:
func method(data interface{})
.. because I need to process different structs which have common fields/methods. In this function I use data tens or hundreds of times, in different places. It's really unpleasant to add switch a.(type) { case .. case .. all the time.
Is there a way to create a variable with just one switch with needed type and then just use this variable everywhere later? Something like:
var a .... // something here
switch data.(type) {
case *Struct1:
a = data.(*Struct1)
case *Struct2:
a = data.(*Struct2)
}
// Continue with 'a' only
a.Param = 15
fmt.Println(a.String())
Go is a statically typed language, the type of a must be known at compile time. And since Go does not support generics yet, you can't do what you want.
Try to come up with some other solution, e.g. abstract away the things you want to do with a into an interface, and have the concrete types implement that interface. Then a can be a variable of this interface type, and you can call methods of it.
If you can achieve this, actually you can even change the parameter of the data type to this interface, and no type assertion or type switch is needed.
Alternatively you could use reflection to access common fields (either for get or set) identified by their name, but reflection provides no compile-time guarantee, and it's usually less efficient. For an example how to do that, see this question: Assert interface to its type
You can't do what you ask for in your question directly, go is statically typed, so you can't have one variable that can hold different types, and still access that variable as if it is typed.
If you're only working on the common struct fields in your method, you are perhaps better off gathering all the common variables in its own struct, illustrated below as the commons struct and have your method take that type as an argument
package main
import (
"fmt"
)
type commons struct {
name string
age int
}
type structA struct {
commons
other_stuff int
}
type structB struct {
commons
foo string
}
func method(c* commons) {
fmt.Println(c)
c.age +=1
}
func main() {
a := structA{commons{"foo", 44}, 1}
b := structB{commons{"bar", 33}, "test"}
method(&a.commons)
method(&b.commons)
fmt.Println(a)
}
Go playground
I can't figure out what is your real goal but if the "method" you want to write handles common fields from similar structures, and you cannot fix original structures using Type Embedding, as #nos said above, then you can try to make another structure for method-internal use:
var v Vehicle // with common fields
switch data.(type) {
case *Car:
v.Handle = data.(*Car).Handle // or CircleHandle
case *Motorcycle:
v.Handle = data.(*Motorcycle).Handle // or BarHandle
}
v.Degree = 15
v.Speed = 50
v.Direction = "left"
v.Style = "rough"
/// so many things on `v`...
steering(v)
I think it is not a good approach but sometimes... :-)

unmarshalling generic json with a type lookup map

I'm following up on Golang Decoding Generic JSON Objects to One of Many Formats as a way to unmarshal generic json. I'm going to have a multitude of different types tho which can be added by others, so hardcoding case statements is not feasible.
I also don't want to hardcode the type as a string, but let the ones using the library chose the "lookup" name, in case they want to rename their underlying structs later.
I am basically looking for something like this:
type myInterface interface {
Something() // irrelevant, just to show you It's not about interface{}
}
type myBar struct {} // fulfils myInterface
type mySomething struct {} // fulfils myInterface
var types = make(map[string]type) // <--- Obvious Pseudo code ;)
types["foo:bar"] = myBar // done by whoever uses the library
types["1230988"] = mySomething // ...
type storageWrapper struct {
Type string
Data json.RawMessage
}
func loadSomething(id string) myInterface {
buf := db.load(id) // pseudo code but you get the idea
sw := &storageWrapper{}
json.Unmarshal(buf, sw)
// now the interesting part
targetType := types[sw.Type]
thing := &targetType{}
json.Unmarshal(sw.Data, thing)
return thing
}
I have this feeling that I'm overthinking the whole Problem. Or that I'm trying to bend Go into something that conflicts with its underlying philosophy. I'm very open and thankful for any advice that suggests a different approach to the whole Problem
Have types be a map[string]myInterface, and to register a type, have callers store an empty value of that type (not a reference) into the map. Then, to unmarshal, you can "get the type" by copying the empty value out of the map, unmarshaling into it, and returning it (or a reference to it). The interface value will do the job of identifying which type is wanted. Plus, if users want to default some fields to non-zero/empty values in case they're not provided in the JSON, they can actually do that by storing those values within the struct in the type map.

What's the meaning of interface{}?

I'm new to interfaces and trying to do SOAP request by github
I don't understand the meaning of
Msg interface{}
in this code:
type Envelope struct {
Body `xml:"soap:"`
}
type Body struct {
Msg interface{}
}
I've observed the same syntax in
fmt.Println
but don't understand what's being achieved by
interface{}
Note: Go 1.18 (Q1 2022) does rename interface{} to any (alias for interface{}).
See issue 49884, CL 368254 and commit 2580d0e.
See the last part of this answer.
You can refer to the article "How to use interfaces in Go" (based on "Russ Cox’s description of interfaces"):
What is an interface?
An interface is two things:
it is a set of methods,
but it is also a type
The interface{} type (or any with Go 1.18+), the empty interface is the interface that has no methods.
Since there is no implements keyword, all types implement at least zero methods, and satisfying an interface is done automatically, all types satisfy the empty interface.
That means that if you write a function that takes an interface{} value as a parameter, you can supply that function with any value.
(That is what Msg represents in your question: any value)
func DoSomething(v interface{}) {
// ...
}
func DoSomething(v any) {
// ...
}
Here’s where it gets confusing:
inside of the DoSomething function, what is v's type?
Beginner gophers are led to believe that “v is of any type”, but that is wrong.
v is not of any type; it is of interface{} type.
When passing a value into the DoSomething function, the Go runtime will perform a type conversion (if necessary), and convert the value to an interface{} value.
All values have exactly one type at runtime, and v's one static type is interface{} (or any with Go 1.18+).
An interface value is constructed of two words of data:
one word is used to point to a method table for the value’s underlying type,
and the other word is used to point to the actual data being held by that value.
Addendum: This is were Russ's article is quite complete regarding an interface structure:
type Stringer interface {
String() string
}
Interface values are represented as a two-word pair giving a pointer to information about the type stored in the interface and a pointer to the associated data.
Assigning b to an interface value of type Stringer sets both words of the interface value.
The first word in the interface value points at what I call an interface table or itable (pronounced i-table; in the runtime sources, the C implementation name is Itab).
The itable begins with some metadata about the types involved and then becomes a list of function pointers.
Note that the itable corresponds to the interface type, not the dynamic type.
In terms of our example, the itable for Stringer holding type Binary lists the methods used to satisfy Stringer, which is just String: Binary's other methods (Get) make no appearance in the itable.
The second word in the interface value points at the actual data, in this case a copy of b.
The assignment var s Stringer = b makes a copy of b rather than point at b for the same reason that var c uint64 = b makes a copy: if b later changes, s and c are supposed to have the original value, not the new one.
Values stored in interfaces might be arbitrarily large, but only one word is dedicated to holding the value in the interface structure, so the assignment allocates a chunk of memory on the heap and records the pointer in the one-word slot.
Issue 33232 seems to point out to any as an alias to interface{} in Go 1.18 (Q1 2022)
Russ Cox explains:
'any' being only for constraints is a detail that will be in every writeup of generics - books, blog posts, and so on.
If we think we are likely to allow it eventually, it makes sense to allow it from the start and avoid invalidating all that written material.
'any' being only for constraints is an unexpected cut-out that reduces generality and orthogonality of concepts.
It's easy to say "let's just wait and see", but prescribing uses tends to create much more jagged features than full generality. We saw this with type aliases as well (and resisted almost all the proposed cut-outs, thankfully).
If 'any' is allowed in generics but not non-generic code, then it might encourage people to overuse generics simply because 'any' is nicer to write than 'interface{}', when the decision about generics or not should really be made by considering other factors.
If we allow 'any' for ordinary non-generic usage too, then seeing interface{} in code could serve as a kind of signal that the code predates generics and has not yet been reconsidered in the post-generics world.
Some code using interface{} should use generics. Other code should continue to use interfaces.
Rewriting it one way or another to remove the text 'interface{}' would give people a clear way to see what they'd updated and hadn't. (Of course, some code that might be better with generics must still use interface{} for backwards-compatibility reasons, but it can still be updated to confirm that the decision was considered and made.)
That thread also includes an explanation about interface{}:
It's not a special design, but a logical consequence of Go's type declaration syntax.
You can use anonymous interfaces with more than zero methods:
func f(a interface{Foo(); Bar()}) {
a.Foo()
a.Bar()
}
Analogous to how you can use anonymous structs anywhere a type is expected:
func f(a struct{Foo int; Bar string}) {
fmt.Println(a.Foo)
fmt.Println(a.Bar)
}
An empty interface just happens to match all types because all types have at least zero methods.
Removing interface{} would mean removing all interface functionality from the language if you want to stay consistent / don't want to introduce a special case.
interface{} means you can put value of any type, including your own custom type. All types in Go satisfy an empty interface (interface{} is an empty interface).
In your example, Msg field can have value of any type.
Example:
package main
import (
"fmt"
)
type Body struct {
Msg interface{}
}
func main() {
b := Body{}
b.Msg = "5"
fmt.Printf("%#v %T \n", b.Msg, b.Msg) // Output: "5" string
b.Msg = 5
fmt.Printf("%#v %T", b.Msg, b.Msg) //Output: 5 int
}
Go Playground
There are already good answers here. Let me add my own too for others who want to understand it intuitively:
Interface
Here's an interface with one method:
type Runner interface {
Run()
}
So any type that has a Run() method satisfies the Runner interface:
type Program struct {
/* fields */
}
func (p Program) Run() {
/* running */
}
func (p Program) Stop() {
/* stopping */
}
Although the Program type has also a Stop method, it still satisfies the Runner interface because all that is needed is to have all of the methods of an interface to satisfy it.
So, it has a Run method and it satisfies the Runner interface.
Empty Interface
Here's a named empty interface without any methods:
type Empty interface {
/* it has no methods */
}
So any type satisfies this interface. Because, no method is needed to satisfy this interface. For example:
// Because, Empty interface has no methods, following types satisfy the Empty interface
var a Empty
a = 5
a = 6.5
a = "hello"
But, does the Program type above satisfy it? Yes:
a = Program{} // ok
interface{} is equal to the Empty interface above.
var b interface{}
// true: a == b
b = a
b = 9
b = "bye"
As you see, there's nothing mysterious about it but it's very easy to abuse. Stay away from it as much as you can.
https://play.golang.org/p/A-vwTddWJ7G
It's called the empty interface and is implemented by all types, which means you can put anything in the Msg field.
Example :
body := Body{3}
fmt.Printf("%#v\n", body) // -> main.Body{Msg:3}
body = Body{"anything"}
fmt.Printf("%#v\n", body) // -> main.Body{Msg:"anything"}
body = Body{body}
fmt.Printf("%#v\n", body) // -> main.Body{Msg:main.Body{Msg:"anything"}}
This is the logical extension of the fact that a type implements an interface as soon as it has all methods of the interface.
From the Golang Specifications:
An interface type specifies a method set called its interface. A
variable of interface type can store a value of any type with a method
set that is any superset of the interface. Such a type is said to
implement the interface. The value of an uninitialized variable of
interface type is nil.
A type implements any interface comprising any subset of its methods
and may therefore implement several distinct interfaces. For instance,
all types implement the empty interface:
interface{}
The concepts to graps are:
Everything has a Type. You can define a new type, let's call it T. Let's say now our Type T has 3 methods: A, B, C.
The set of methods specified for a type is called the "interface type". Let's call it in our example: T_interface. Is equal to T_interface = (A, B, C)
You can create an "interface type" by defining the signature of the methods. MyInterface = (A, )
When you specify a variable of type, "interface type", you can assign to it only types which have an interface that is a superset of your interface.
That means that all the methods contained in MyInterface have to be contained inside T_interface
You can deduce that all the "interface types" of all the types are a superset of the empty interface.
An example that extends the excellent answer by #VonC and the comment by #NickCraig-Wood. interface{} can point to anything and you need a cast/type assertion to use it.
package main
import (
. "fmt"
"strconv"
)
var c = cat("Fish")
var d = dog("Bone")
func main() {
var i interface{} = c
switch i.(type) {
case cat:
c.Eat() // Fish
}
i = d
switch i.(type) {
case dog:
d.Eat() // Bone
}
i = "4.3"
Printf("%T %v\n", i, i) // string 4.3
s, _ := i.(string) // type assertion
f, _ := strconv.ParseFloat(s, 64)
n := int(f) // type conversion
Printf("%T %v\n", n, n) // int 4
}
type cat string
type dog string
func (c cat) Eat() { Println(c) }
func (d dog) Eat() { Println(d) }
i is a variable of an empty interface with a value cat("Fish"). It is legal to create a method value from a value of interface type. See https://golang.org/ref/spec#Interface_types.
A type switch confirms i interface type is cat("Fish") . See https://golang.org/doc/effective_go.html#type_switch. i is then reassigned to dog("Bone"). A type switch confirms that i interface’s type has changed to dog("Bone") .
You can also ask the compiler to check that the type T implements the interface I by attempting an assignment: var _ I = T{}. See https://golang.org/doc/faq#guarantee_satisfies_interface and https://stackoverflow.com/a/60663003/12817546.
All types implement the empty interface interface{}. See https://talks.golang.org/2012/goforc.slide#44 and https://golang.org/ref/spec#Interface_types . In this example, i is reassigned, this time to a string "4.3".i is then assigned to a new string variable s with i.(string) before s is converted to a float64 type f using strconv. Finally f is converted to n an int type equal to 4. See What is the difference between type conversion and type assertion?
Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly. See https://golang.org/doc/faq#generics.
Interface is a type which is unknown at compile time
It is a contract between object and the struct type to satisfy with common functionality
or
common functionality acting on different types of struct objects
for example in the below code PrintDetails is a common functionality acting on different types of structs as Engineer,Manager,
Seniorhead
please find the example code
interface examplehttps://play.golang.org/p/QnAqEYGiiF7
A method can bind to any type(int, string, pointer, and so on) in GO
Interface is a way of declear what method one type should have, as long as A type has implement those methods, this can be assigned to this interface.
Interface{} just has no declear of method, so it can accept any type

Best practice for unions in Go

Go has no unions. But unions are necessary in many places. XML makes excessive use of unions or choice types. I tried to find out, which is the preferred way to work around the missing unions. As an example I tried to write Go code for the non terminal Misc in the XML standard which can be either a comment, a processing instruction or white space.
Writing code for the three base types is quite simple. They map to character arrays and a struct.
type Comment Chars
type ProcessingInstruction struct {
Target *Chars
Data *Chars
}
type WhiteSpace Chars
But when I finished the code for the union, it got quite bloated with many redundant functions. Obviously there must be a container struct.
type Misc struct {
value interface {}
}
In order to make sure that the container holds only the three allowed types I made the value private and I had to write for each type a constructor.
func MiscComment(c *Comment) *Misc {
return &Misc{c}
}
func MiscProcessingInstruction (pi *ProcessingInstruction) *Misc {
return &Misc{pi}
}
func MiscWhiteSpace (ws *WhiteSpace) *Misc {
return &Misc{ws}
}
In order to be able to test the contents of the union it was necessary to write three predicates:
func (m Misc) IsComment () bool {
_, itis := m.value.(*Comment)
return itis
}
func (m Misc) IsProcessingInstruction () bool {
_, itis := m.value.(*ProcessingInstruction)
return itis
}
func (m Misc) IsWhiteSpace () bool {
_, itis := m.value.(*WhiteSpace)
return itis
}
And in order to get the correctly typed elements it was necessary to write three getters.
func (m Misc) Comment () *Comment {
return m.value.(*Comment)
}
func (m Misc) ProcessingInstruction () *ProcessingInstruction {
return m.value.(*ProcessingInstruction)
}
func (m Misc) WhiteSpace () *WhiteSpace {
return m.value.(*WhiteSpace)
}
After this I was able to create an array of Misc types and use it:
func main () {
miscs := []*Misc{
MiscComment((*Comment)(NewChars("comment"))),
MiscProcessingInstruction(&ProcessingInstruction{
NewChars("target"),
NewChars("data")}),
MiscWhiteSpace((*WhiteSpace)(NewChars(" \n")))}
for _, misc := range miscs {
if (misc.IsComment()) {
fmt.Println ((*Chars)(misc.Comment()))
} else if (misc.IsProcessingInstruction()) {
fmt.Println (*misc.ProcessingInstruction())
} else if (misc.IsWhiteSpace()) {
fmt.Println ((*Chars)(misc.WhiteSpace()))
} else {
panic ("invalid misc");
}
}
}
You see there is much code looking almost the same. And it will be the same for any other union. So my question is: Is there any way to simplify the way to deal with unions in Go?
Go claims to simplify programing work by removing redundancy. But I think the above example shows the exact opposite. Did I miss anything?
Here is the complete example: http://play.golang.org/p/Zv8rYX-aFr
As it seems that you're asking because you want type safety, I would firstly argue that your initial
solution is already unsafe as you have
func (m Misc) Comment () *Comment {
return m.value.(*Comment)
}
which will panic if you haven't checked IsComment before. Therefore this solution has no benefits over
a type switch as proposed by Volker.
Since you want to group your code you could write a function that determines what a Misc element is:
func IsMisc(v {}interface) bool {
switch v.(type) {
case Comment: return true
// ...
}
}
That, however, would bring you no compiler type checking either.
If you want to be able to identify something as Misc by the compiler then you should
consider creating an interface that marks something as Misc:
type Misc interface {
ImplementsMisc()
}
type Comment Chars
func (c Comment) ImplementsMisc() {}
type ProcessingInstruction
func (p ProcessingInstruction) ImplementsMisc() {}
This way you could write functions that are only handling misc. objects and get decide later
what you really want to handle (Comments, instructions, ...) in these functions.
If you want to mimic unions then the way you wrote it is the way to go as far as I know.
I think this amount of code might be reduced, e.g. I personally do not think that safeguarding type Misc against containing "illegal" stuff is really helpful: A simple type Misc interface{} would do, or?
With that you spare the constructors and all the Is{Comment,ProcessingInstruction,WhiteSpace} methods boil down to a type switch
switch m := misc.(type) {
Comment: fmt.Println(m)
...
default: panic()
}
Thats what package encoding/xml does with Token.
I am not sure to understand your issue. The 'easy' way to do it would be like the encoding/xml package with interface{}. If you do not want to use interfaces, then you can do something like you did.
However, as you stated, Go is a typed language and therefore should be use for typed needs.
If you have a structured XML, Go can be a good fit, but you need to write your schema. If you want a variadic schema (one given field can have multiple types), then you might be better off with an non-typed language.
Very useful tool for json that could easily rewritten for xml:
http://mholt.github.io/json-to-go/
You give a json input and it gives you the exact Go struct. You can have multiple types, but you need to know what field has what type. If you don't, you need to use the reflection and indeed you loose a lot of the interest of Go.
TL;DR You don't need a union, interface{} solves this better.
Unions in C are used to access special memory/hardware. They also subvert the type system. Go does not have the language primitives access special memory/hardware, it also shunned volatile and bit-fields for the same reason.
In C/C++ unions can also be used for really low level optimization / bit packing. The trade off: sacrifice the type system and increase complexity in favor of saving some bits. This of course comes with all the warnings about optimizations.
Imagine Go had a native union type. How would the code be better? Rewrite the code with this:
// pretend this struct was a union
type MiscUnion struct {
c *Comment
pi *ProcessingInstruction
ws *WhiteSpace
}
Even with a builtin union accessing the members of MiscUnion requires a runtime check of some kind. So using an interface is no worse off. Arguably the interface is superior as the runtime type checking is builtin (impossible to get wrong) and has really nice syntax for dealing with it.
One advantage of a union type is static type check to make sure only proper concrete types where put in a Misc. The Go way of solving this is "New..." functions, e.g. MiscComment, MiscProcessingInstruction, MiscWhiteSpace.
Here is a cleaned up example using interface{} and New* functions: http://play.golang.org/p/d5bC8mZAB_

Resources