Michael Lorton
Michael Lorton

Reputation: 44436

Approximating structural typing in a Golang function

A library is providing me a series of types like this:

type T1 struct {
  n int
}
type T2 struct {
  n int
}
type T3 struct {
  n int
}

there is a marker interface like this

type S interface { 
   isS()
}

func (T1) isS() {}
func (T2) isS() {}
func (T3) isS() {}

I am trying to write a function:

func getN(s S) int {
  return s.n
}

Obviously, that won’t compile, and it shouldn’t.

What I am doing now is

func getN(s S) int {
  if t1, ok := s.(T1); ok {
     return t1
  }
  if t2, ok := s.(T2); ok {
     return t2
  }
  ...
}

That works, but it unbearably awful. The library adds new T structures fairly often and it’s a disastrous violation of open/closed. Any tolerable language has a facility for this kind of situation; what is Golang’s?

Upvotes: 1

Views: 167

Answers (1)

LukasDeco
LukasDeco

Reputation: 425

Create a method on the interface that returns the type you are looking for. That will get it to compile correctly.

type S interface { 
   GetN()
}

func (T1) GetN() int {
// impl
}
func (T2) GetN() int  {
// impl
}
func (T3) GetN() int  {
// impl
}

then if you still need your interesting function that takes an interface, you can do this:

func getN(s S) int {
  return s.GetN()
}

Upvotes: 0

Related Questions