Interface assertion

Assertion can also be done from one interface to another. Imagine having two different interfaces:

type Fooer interface {
Foo()
}

type Barer interface {
Bar()
}

Let's define a type that implements one of them and another that implements both:

type A int

func (A) Foo() {}

type B int

func (B) Bar() {}
func (B) Foo() {}

If we define a new variable for the first interface, the assertion to the second is going to be successful only if the underlying value has a type that implements both; otherwise, it's going to fail:

func main() {
var a Fooer

a = A(0)
v, ok := a.(Barer)
fmt.Println(v, ok)

a = B(0)
v, ok = a.(Barer)
fmt.Println(v, ok)
}

A full example is available here: https://play.golang.org/p/bX2rnw5pRXJ.

A use case scenario could be having the io.Reader interface, checking out whether it is also an io.Closer interface, and wrapping it in the ioutil.NopCloser function (which returns an io.ReadCloser interface) if not:

func Closer(r io.Reader) io.ReadCloser {
if rc, ok := r.(io.ReadCloser); ok {
return rc
}
return ioutil.NopCloser(r)
}

func main() {
log.Printf("%T", Closer(&bytes.Buffer{}))
log.Printf("%T", Closer(&os.File{}))
}

A full example is available here: https://play.golang.org/p/hUEsDYHFE7i.

There is an important aspect to interfaces that we need to underline before jumping onto reflection—its representation is always a tuple interface-value where the value is a concrete type and cannot be another interface.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.214.155