Structs and interface types - go

Could someone please explain (or if it's a long thing to explain at least point me to some documentation) why this code is behaving like it does. It's a bit lengthy but I couldn't figure out a good way of shortening it without losing too much info.
What confuses me is that I need to have the method "Find" on each type of struct for it to be recognized as the type it is. With Find on only the baseTypeImp is it printing that each is baseTypeImp, if I have it on baseTypeImp and advancedBaseTypeImp are those two identified correctly, but not the last type.
PlaygroundLink
My Code
package main
import (
"fmt"
"reflect"
)
type BaseType interface {
Name() string
Find(string) BaseType
Children() []BaseType
Options()
}
type baseTypeImp struct {
name string
children []BaseType
}
func (b baseTypeImp) Options() {
fmt.Println("Not implemented")
}
func (b baseTypeImp) Find(name string) BaseType {
if b.name == name {
return b
}
for _, c := range b.children {
if m := c.Find(name); m != nil {
return m
}
}
return nil
}
func (b baseTypeImp) Name() string {
return b.name
}
func (b baseTypeImp) Children() []BaseType {
return b.children
}
type AdvancedBaseType interface {
Value()
}
type advancedBaseTypeImp struct {
baseTypeImp
}
func (a advancedBaseTypeImp) Options() {
fmt.Println("Is implemented")
}
func (a advancedBaseTypeImp) Value() {
fmt.Println("Value called")
}
func (a advancedBaseTypeImp) Find(name string) BaseType {
if a.name == name {
return a
}
for _, c := range a.children {
if m := c.Find(name); m != nil {
return m
}
}
return nil
}
type reallyAdvancedBaseTypeImp advancedBaseTypeImp
func newThingy(name, variant string, children []BaseType) BaseType {
base := baseTypeImp{name: name, children: children}
switch variant {
case "advanced":
return advancedBaseTypeImp{baseTypeImp: base}
case "reallyAdvanced":
return reallyAdvancedBaseTypeImp{baseTypeImp: base}
}
return base
}
func whatType(b BaseType) {
if b == nil {
return
}
fooType := reflect.TypeOf(b)
fmt.Println(b.Name(), " is type ", fooType.Name())
b.Options()
}
func main() {
advanced := make([]BaseType, 0, 5)
for i := 0; i < 5; i++ {
advanced = append(advanced, newThingy(fmt.Sprintf("Advanced %d", i), "advanced", nil))
}
reallyAdvanced := make([]BaseType, 0, 2)
for i := 0; i < 2; i++ {
reallyAdvanced = append(reallyAdvanced, newThingy(fmt.Sprintf("ReallyAdvanced %d", i), "reallyAdvanced", advanced[i:i+3]))
}
basic := newThingy("Basic parent", "basic", reallyAdvanced)
whatType(basic.Find("Basic parent"))
for i := 0; i < 2; i++ {
whatType(basic.Find(fmt.Sprintf("Advanced %d", i)))
whatType(basic.Find(fmt.Sprintf("ReallyAdvanced %d", i)))
}
}
The output now is:
Basic parent is type baseTypeImp
Not implemented
Advanced 0 is type advancedBaseTypeImp
Is implemented
ReallyAdvanced 0 is type baseTypeImp
Not implemented
Advanced 1 is type advancedBaseTypeImp
Is implemented
ReallyAdvanced 1 is type baseTypeImp
Not implemented
What I'd like to have is:
Basic parent is type baseTypeImp
Not implemented
Advanced 0 is type advancedBaseTypeImp
Is implemented
ReallyAdvanced 0 is type reallyAdvancedBaseTypeImp
Is implemented
Advanced 1 is type advancedBaseTypeImp
Is implemented
ReallyAdvanced 1 is type reallyAdvancedBaseTypeImp
Is implemented
Is there a way to get this working without having to implement Find on each level? It kind of defeats the purpose of having the common methods in the top layer struct. And of course, if possible explain why it's behaving the way it does.

When you embed a struct into another one, the outer struct gets the methods of the embedded one.
type inner struct {
}
func (i inner) f() {}
type outer struct {
inner
}
...
x:=outer{}
x.f()
You can think of this as syntactic sugar for:
type outer2 struct {
i inner
}
y.i.f()
When you embed inner without a field name, you simply drop the i in the call. You can still call x.inner.f() in the first example.
When you redefine a type, it does not get the methods defined for its base type.
type newtype inner
newtype does not have f() defined. However, if inner also embeds other structs (like you do), then those are still embedded in the new type, so those function are defined:
type deepest struct {}
func (deepest) deep() {}
type inner struct{}
func (inner) in() {}
type outer inner
Above, the type outer does not have the function in, but it has deep.
So when you call reallyAdvancedBaseTypeImp.Find(), what you're really doing is reallyAdvancedBaseTypeImp.baseTypeImp.Find(), which works on that portion of the struct. That's why you're getting the types you get.
You're trying to emulate method overriding. You can't really do that. Formulate your problem in a different way.

Related

How to implement a generic Either type in Go?

With the new generics in Go 1.18, I thought it might be possible to create a 'Either[A,B]' type that can be used to express that something could be either of type A or type B.
A situation where you might use this is in situations where a function might return one of two possible values as a result (e.g. one for 'normal' result and one for an error).
I know the 'idiomatic' Go for errors would be to return both a 'normal' value and an error value, returning a nil for either the error or the value. But... it sort of bothers me that we are essentially saying 'this returns A and B' in the type, where what we really mean to say is 'this returns A or B'.
So I thought maybe we can do better here, and I thought this might also be a good exercise to see/test the boundaries of what we can do with these new generics.
Sadly,try as I might, so far I have not been able solve the exercise and get anything working/compiling. From one of my failed attempts, here is an interface I'd like to implement somehow:
//A value of type `Either[A,B]` holds one value which can be either of type A or type B.
type Either[A any, B any] interface {
// Call either one of two functions depending on whether the value is an A or B
// and return the result.
Switch[R any]( // <=== ERROR: interface methods must have no type parameters
onA func(a A) R),
onB func(b B) R),
) R
}
Unfortunately, this fails rather quickly because declaring this interface isn't allowed by Go. Apparantly because 'interface methods must have no type parameters'.
How do we work around this restriction? Or is there simply no way to create a 'type' in Go that accurately expresses the idea that 'this thing is/returns either A or B' (as opposed to a tuple of both A and B).
If I had to do this, I would look up a functional programming language(like OCaml) and knock-off their solution of the either type..
package main
import (
"errors"
"fmt"
"os"
)
type Optional[T any] interface {
get() (T, error)
}
type None[T any] struct {
}
func (None[T]) get() (T, error) {
var data T
return data, errors.New("No data present in None")
}
type Some[T any] struct {
data T
}
func (s Some[T]) get() (T, error) {
return s.data, nil
}
func CreateNone[T any]() Optional[T] {
return None[T]{}
}
func CreateSome[T any](data T) Optional[T] {
return Some[T]{data}
}
type Either[A, B any] interface {
is_left() bool
is_right() bool
find_left() Optional[A]
find_right() Optional[B]
}
type Left[A, B any] struct {
data A
}
func (l Left[A, B]) is_left() bool {
return true
}
func (l Left[A, B]) is_right() bool {
return false
}
func left[A, B any](data A) Either[A, B] {
return Left[A, B]{data}
}
func (l Left[A, B]) find_left() Optional[A] {
return CreateSome(l.data)
}
func (l Left[A, B]) find_right() Optional[B] {
return CreateNone[B]()
}
type Right[A, B any] struct {
data B
}
func (r Right[A, B]) is_left() bool {
return false
}
func (r Right[A, B]) is_right() bool {
return true
}
func right[A, B any](data B) Either[A, B] {
return Right[A, B]{data}
}
func (r Right[A, B]) find_left() Optional[A] {
return CreateNone[A]()
}
func (r Right[A, B]) find_right() Optional[B] {
return CreateSome(r.data)
}
func main() {
var e1 Either[int, string] = left[int, string](4143)
var e2 Either[int, string] = right[int, string]("G4143")
fmt.Println(e1)
fmt.Println(e2)
if e1.is_left() {
if l, err := e1.find_left().get(); err == nil {
fmt.Printf("The int is: %d\n", l)
} else {
fmt.Fprintln(os.Stderr, err)
}
}
if e2.is_right() {
if r, err := e2.find_right().get(); err == nil {
fmt.Printf("The string is: %s\n", r)
} else {
fmt.Fprintln(os.Stderr, err)
}
}
}
The Either could be modeled as a struct type with one unexported field of type any/interface{}. The type parameters would be used to ensure some degree of compile-time type safety:
type Either[A, B any] struct {
value any
}
func (e *Either[A,B]) SetA(a A) {
e.value = a
}
func (e *Either[A,B]) SetB(b B) {
e.value = b
}
func (e *Either[A,B]) IsA() bool {
_, ok := e.value.(A)
return ok
}
func (e *Either[A,B]) IsB() bool {
_, ok := e.value.(B)
return ok
}
If Switch has to be declared as a method, it can't be parametrized in R by itself. The additional type parameter must be declared on the type definition, however this might make usage a bit cumbersome because then R must be chosen upon instantiation.
A standalone function seems better — in the same package, to access the unexported field:
func Switch[A,B,R any](e *Either[A,B], onA func(A) R, onB func(B) R) R {
switch v := e.value.(type) {
case A:
return onA(v)
case B:
return onB(v)
}
}
A playground with some code and usage: https://go.dev/play/p/g-NmE4KZVq2
You can use the https://github.com/samber/mo library (disclaimer: I'm the project author).
Either signature is:
type Either[L any, R any] struct {}
Some examples:
import "github.com/samber/mo"
left := lo.Left[string, int]("hello")
left.LeftOrElse("world")
// hello
left.RightOrElse(1234)
// 1234
left.IsLeft()
// true
left.IsRight()
// false
Your question about a Switch pattern can be implemented this way:
import "github.com/samber/mo"
left := lo.Left[string, int]("hello")
result := left.Match(
func(s string) Either[string, int] {
// <-- should enter here
return lo.Right[string, int](1234)
},
func(i int) Either[string, int] {
// <-- should not enter here
return lo.Right[string, int](i * 42)
},
)
result.LeftOrElse("world")
// world
result.RightOrElse(42)
// 1234
A solution finally came to me. The key was defining the 'Either' type as a 'struct' instead of an interface.
type Either[A any, B any] struct {
isA bool
a A
b B
}
func Switch[A any, B any, R any](either Either[A, B],
onA func(a A) R,
onB func(b B) R,
) R {
if either.isA {
return onA(either.a)
} else {
return onB(either.b)
}
}
func MakeA[A any, B any](a A) Either[A, B] {
var result Either[A, B]
result.isA = true
result.a = a
return result
}
func MakeB[A any, B any](b B) Either[A, B] {
... similar to MakeA...
}
That works, but at the 'price' of really still using a 'tuple-like' implementation under the hood were we store both an A and a B but ensure it is only possible to use one of them via the public API.
I suspect this is the best we can do given the restrictions Go puts on us.
If someone has a 'workaround' that doesn't essentially use 'tuples' to represent 'unions'. I would consider that a better answer.

How to use pointers to interface in go as internal data structure for collection-like types?

TLDR; I need to use pointers to interface e.g. *Comparable as an internal Data's object in my Node as a part of Tree. Data should conform to pointer to Comparable interface that has only one method Less which compares two objects of Comparable interface type.
If I am using just Comparable as type for Data in Node, without pointer, everything works fine. However after I switch to *Comparable compiler gives strange errors and code won't compile
Code with Comparable:
package main
type Comparable interface {
Less(than Comparable) bool
}
type Node struct {
Data Comparable
}
func NewNode(data Comparable) *Node {
return &Node{Data: data} }
type Tree struct {
root *Node
}
func NewTree() *Tree {
return &Tree{}
}
func (t *Tree) insert(data Comparable) {
if t.root == nil || t.root.Data.Less(data) {
t.root = NewNode(data)
}
}
type Row struct {
Row []string
}
func NewRow(row[] string) *Row {
return &Row{Row: row}
}
func (r Row) Less(other Comparable) bool {
return r.Row[0] < other.(Row).Row[0]
}
func main() {
t := NewTree()
t.insert(*NewRow([]string{"123"}))
fmt.Printf("%v\n", t.root.Data.(Row).Row)
}
tests:
package main
import (
"reflect"
"testing"
)
func TestInsert(t *testing.T) {
d := []string{"42"}
tree := NewTree()
tree.insert(*NewRow(d))
if !reflect.DeepEqual(tree.root.Data.(Row).Row, d) {
t.Error("returned elements are not matching")
}
}
func TestInsert2x(t *testing.T) {
d1 := []string{"42"}
d2 := []string{"99"}
tree := NewTree()
tree.insert(*NewRow(d1))
tree.insert(*NewRow(d2))
if !reflect.DeepEqual(tree.root.Data.(Row).Row, d2) {
t.Error("returned elements are not matching")
}
}
However when I convert Comparable to *Comparable, everything breaks and the root cause is something like *Row is not equal to *Comparable compiler error:
for line return r.Row[0] < other.(*Row).Row[0]
Invalid type assertion: other.(*Row) (non-interface type *Comparable on left)
and for line if t.root == nil || t.root.Data.Less(data) {
Unresolved reference 'Less'
package main
type Comparable interface {
Less(than *Comparable) bool
}
type Node struct {
Data *Comparable
}
func NewNode(data *Comparable) *Node {
return &Node{Data: data}
}
type Tree struct {
root *Node
}
func NewTree() *Tree {
return &Tree{}
}
func (t *Tree) insert(data *Comparable) {
if t.root == nil || t.root.Data.Less(data) {
t.root = NewNode(data)
}
}
type Row struct {
Row []string
}
func NewRow(row[] string) *Row {
return &Row{Row: row}
}
func (r *Row) Less(other *Comparable) bool {
return r.Row[0] < other.(*Row).Row[0]
}
func main() {
t := NewTree()
t.insert(NewRow([]string{"123"}))
fmt.Printf("%v\n", t.root.Data.(*Row).Row)
}
tests:
package main
import (
"reflect"
"testing"
)
func TestInsert(t *testing.T) {
d := []string{"42"}
tree := NewTree()
tree.insert(NewRow(d))
if !reflect.DeepEqual(tree.root.Data.(*Row).Row, d) {
t.Error("returned elements are not matching")
}
}
func TestInsert2x(t *testing.T) {
d1 := []string{"42"}
d2 := []string{"99"}
tree := NewTree()
tree.insert(NewRow(d1))
tree.insert(NewRow(d2))
if !reflect.DeepEqual(tree.root.Data.(*Row).Row, d2) {
t.Error("returned elements are not matching")
}
}
The question is how to use *Comparable as type of Data in Node so that code above compiles. I tried a couple ugly options with interface{} type for Data and explicit casts everywhere. This approach I didn't like as it is very unsafe.
You can check all code parts in my github repo
Interfaces can accept both structs and pointers to structs.
You can pass in a pointer to Row (*Row) to Tree.insert(data Comparable), by combining your 1st Tree.insert(data Comparable) function definition with your 2nd main() function calls.
Here's a full running example, also on Go Playground: https://play.golang.org/p/Gh_RT3R-Fy0 .
package main
import (
"fmt"
)
type Comparable interface {
Less(than Comparable) bool
}
type Node struct {
Data Comparable
}
func NewNode(data Comparable) *Node {
return &Node{Data: data}
}
type Tree struct {
root *Node
}
func NewTree() *Tree {
return &Tree{}
}
func (t *Tree) insert(data Comparable) {
if t.root == nil || t.root.Data.Less(data) {
t.root = NewNode(data)
}
}
type Row struct {
Row []string
}
func NewRow(row []string) *Row {
return &Row{Row: row}
}
func (r Row) Less(other Comparable) bool {
return r.Row[0] < other.(*Row).Row[0]
}
func main() {
t := NewTree()
t.insert(NewRow([]string{"123"}))
fmt.Printf("%v\n", t.root.Data.(*Row).Row)
}
That being said, this is brittle code since the Row.Less function accesses the underlying type of Comparable and assumes the array has at a 0 index value (length > 0).
func (r Row) Less(other Comparable) bool {
return r.Row[0] < other.(*Row).Row[0]
}
It's much better to remove any dependency on the underlying type of Comparable when interface functions are called. You can do this augmenting the Comparable interface and Row.Less definition as follows. In this approach, there's no need to cast in the Row struct definition.
On Go Playground: https://play.golang.org/p/8-71-pEn-zK
type Comparable interface {
Less(than Comparable) bool
CompareValue() string
}
func (r Row) CompareValue() string {
if len(r.Row) == 0 {
return ""
}
return r.Row[0]
}
func (r Row) Less(other Comparable) bool {
return r.CompareValue() < other.CompareValue()
}
For more information on pointer to interfaces, see the Go FAQ on using pointers to interfaces:
https://golang.org/doc/faq#pointer_to_interface
When should I use a pointer to an interface?
Almost never. Pointers to interface values arise only in rare, tricky situations involving disguising an interface value's type for delayed evaluation.
It is a common mistake to pass a pointer to an interface value to a function expecting an interface. The compiler will complain about this error but the situation can still be confusing, because sometimes a pointer is necessary to satisfy an interface. The insight is that although a pointer to a concrete type can satisfy an interface, with one exception a pointer to an interface can never satisfy an interface.
[...]
The one exception is that any value, even a pointer to an interface, can be assigned to a variable of empty interface type (interface{}). Even so, it's almost certainly a mistake if the value is a pointer to an interface; the result can be confusing.

Reflect on list of interfaces

I have read several examples/questions about reflection in Go, but I'm still unable to understand what I'm supposed to do with my list of interfaces.
Below is a stripped down version of the real use case.
I have several types complying with a given interface:
type Foo interface {
Value() int
}
type bar struct {
value int
}
func (b bar) Value() int {
return b.value
}
type baz struct{}
func (b baz) Value() int {
return 42
}
I have a list of such guys
type Foos []Foo
var foos = Foos{
bar{},
baz{},
}
and I would like to traverse this list by changing the value of the members that have a value field.
for k := range foos {
change(&foos[k])
}
But I'm unable to find the right path
func change(g *Foo) {
t := reflect.TypeOf(g).Elem()
fmt.Printf("t: Kind %v, %#v\n", t.Kind(), t)
v := reflect.ValueOf(g).Elem()
fmt.Printf("v: Kind %v, %#v, %v\n", v.Kind(), v, v.CanAddr())
if f, ok := t.FieldByName("value"); ok {
fmt.Printf("f: %#v, OK: %v\n", f, ok)
vf := v.FieldByName("value")
fmt.Printf("vf: %#v: %v\n", vf, vf.CanAddr())
vf.SetInt(51)
}
}
As you can see, I'm not sure how to glue together the TypeOf and ValueOf bits...
The full example is on Go Playground.
There are a couple of issues here. First, it's not possible to set an unexported field. Here's a change to make the field exported:
type Foo interface {
// Rename Value to GetValue to avoid clash with Value field in bar
GetValue() int
}
type bar struct {
// export the field by capitalizing the name
Value int
}
func (b bar) GetValue() int {
return b.Value
}
type baz struct{}
func (b baz) GetValue() int {
return 42
}
The next issue is a bar interface value is not addressable. To fix this, use a *bar in the slice instead instead of a bar:
func (b *bar) GetValue() int {
return b.Value
}
...
var foos = Foos{
&bar{},
baz{},
}
With these changes, we can write the function to set the value:
func change(g Foo) {
v := reflect.ValueOf(g)
// Return if not a pointer to a struct.
if v.Kind() != reflect.Ptr {
return
}
v = v.Elem()
if v.Kind() != reflect.Struct {
return
}
// Set the field Value if found.
v = v.FieldByName("Value")
if !v.IsValid() {
return
}
v.SetInt(31)
}
Run it on the playground
The above answers the question, but it may not be the best solution to the actual problem. A better solution may be to define a setter interface:
type ValueSetter interface {
SetValue(i int)
}
func (b *bar) Value() int {
return b.value
}
func (b *bar) SetValue(i int) {
b.value = i
}
func change(g Foo) {
if vs, ok := g.(ValueSetter); ok {
vs.SetValue(31)
}
}
Run it on the playground
Please don't use your current approach. It has several drawbacks.
It's confusing (as you've discovered)
It's slow. Reflection is always slow.
It's inflexible. Your loop, not the type itself, must understand the capabilities of each type implementation.
Instead, just expand your interface to include a setter method--possibly an optional setter method. Then you can loop through the items and set the value for those that support it. Example:
// FooSetter is an optional interface which allows a Foo to set its value.
type FooSetter interface {
SetValue(int)
}
// SetValue implements the optional FooSetter interface for type bar.
func (b *bar) SetValue(v int) {
b.value = v
}
Then make your loop look like this:
for _, v := range foos {
if setter, ok := v.(FooSetter); ok {
setter.SetValue(51)
}
}
Now when you (or a third party user of your library) adds a type Baz that satisfies the FooSetter interface, you don't have to modify your loop at all.

go type conversion - sort 2 slices of different interfaces using shared interface

The example below contains 2 interfaces Foo and Bar that both implement the same interface Timestamper. It also contains the type ByTimestamp that implements sort.Interface.
As shown in the function main, I would like to use the type ByTimestamp to sort both a slice of Foos and a slice of Bars. However, the code will not compile because it cannot convert foos (type []Foo) to type ByTimestamp and it cannot convert bars (type []Bar) to type ByTimestamp.
Is it possible to sort 2 slices of different interfaces that both implement the same interface with a single type that implements sort.Interface?
package main
import (
"sort"
)
type Timestamper interface {
Timestamp() int64
}
type ByTimestamp []Timestamper
func (b ByTimestamp) Len() int {
return len(b)
}
func (b ByTimestamp) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
func (b ByTimestamp) Less(i, j int) bool {
return b[i].Timestamp() < b[j].Timestamp()
}
type Foo interface {
Timestamper
DoFoo() error
}
type Bar interface {
Timestamper
DoBar() error
}
func getFoos() (foos []Foo) {
// TODO get foos
return
}
func getBars() (bars []Bar) {
// TODO get bars
return
}
func main() {
foos := getFoos()
bars := getBars()
sort.Sort(ByTimestamp(foos))
sort.Sort(ByTimestamp(bars))
}
The Go playground
Yes, it is possible to sort different types using one sort.Interface.
But not the way you were trying to do it. Current Go specification doesn't allow converting one slice type to another. You have to convert each item.
Here's a helper function that does it using reflection:
// ByTimestamp converts a slice of Timestamper into a slice
// that can be sorted by timestamp.
func ByTimestamp(slice interface{}) sort.Interface {
value := reflect.ValueOf(slice)
length := value.Len()
b := make(byTimestamp, 0, length)
for i := 0; i < length; i++ {
b = append(b, value.Index(i).Interface().(Timestamper))
}
return b
}
See the full example here.
And, if you only have a couple of types, then it might make sense to do type-specific conversions instead.

Using reflection to iterate over struct's struct members and calling a method on it

I have a struct that has one or more struct members. Each member is expected to implement a Validator interface.
I want to use reflection to iterate over all struct members and call the interface's Validate() method. For example:
package main
import "fmt"
import "reflect"
type Validator interface {
Validate()
}
type T1 struct {
S string
}
func (p *T1) Validate() {
fmt.Println("HERE 1")
}
type T2 struct {
S string
}
func (p *T2) Validate() {
fmt.Println("HERE 2")
}
type Top struct {
S1 T1
S2 T2
}
func main() {
var t Top
r := reflect.ValueOf(t)
for i := 0; i < r.NumField(); i++ {
f := r.Field(i)
if f.Kind() == reflect.Struct {
validator := f.Interface().(Validator)
validator.Validate()
}
}
}
When run, it outputs:
panic: interface conversion: main.T1 is not main.Validator: missing method Validate
If I change the Validate() methods to accept value (rather than pointer) receivers, then it works. However, I want to use pointer receivers since the structs may grow to be large.
How can I change the reflection code to work where the methods are defined taking pointer receivers?
I also tried using this line:
validator := f.Addr().Interface().(Validator)
to get a pointer, but it then outputs:
panic: reflect.Value.Addr of unaddressable value
None of your values are addressable, so you can't call any methods on them with pointer receivers.
If the S1 and S2 fields can't be pointers, you can still address them if you have a pointer to the Top struct:
r := reflect.ValueOf(&t).Elem()
for i := 0; i < r.NumField(); i++ {
f := r.Field(i)
if f.Kind() == reflect.Struct {
validator := f.Addr().Interface().(Validator)
validator.Validate()
}
}
"Top.S1" is of type "T1" and is different from "*T1" type defined "Validate()".
If you change "Top.S1" to "*T1" type and modify the field type checking, your code will work properly.
type Top struct {
S1 *T1
S2 *T2
}
func main() {
t := Top{&T1{}, &T2{}}
r := reflect.ValueOf(t)
for i := 0; i < r.NumField(); i++ {
f := r.Field(i)
if f.Kind() == reflect.Ptr && f.Elem().Kind() == reflect.Struct {
validator, ok := f.Interface().(Validator)
if ok {
validator.Validate()
} else {
fmt.Println("not ok")
}
}
}
}
https://play.golang.org/p/hHqP6WdMYqT

Resources