4

Given the following code:

package main

import (
    "fmt"
)

type work interface {
    filter() bool
}

type organ struct {
    name string
}

func (s *organ) filter () bool {
    return true;
}


func main() {
    kidney := &organ {
            name : "kidney",    
        }

    _, ok := interface{}(kidney).(work)
    fmt.Println(ok);
}

I did not fully get the following part:

_, ok := interface{}(kidney).(work)

It seems to me, it is converting struct to the interface{} type, which I understand, but why is it required to convert to an interface{} type to check if it satisfies another interface. More specifically, why the following code fails?

ok := kidney.(work)

with error

invalid type assertion: kidney.(work) (non-interface type *organ on left)

soupybionics
  • 4,200
  • 6
  • 31
  • 43
  • 3
    The error message is pretty clear. Type assertions are for interface types only. Also, this check can be done at compile time with `var _ work = &organ{}`. – Ainar-G Nov 03 '16 at 15:32
  • 4
    If you just have a variable of type "organ" you already know the type, so there's no need to assert that it's a worker (just call filter and if it's not a worker the build will fail). Casting a concrete type to an interface and then checking it is code smell in Go; there may be uses for it, but it's probably best if you let the compiler sort it out for you instead. – Sam Whited Nov 03 '16 at 15:42
  • Does this answer your question? [Explanation of checking if value implements interface](https://stackoverflow.com/questions/27803654/explanation-of-checking-if-value-implements-interface) –  Mar 07 '20 at 02:27

1 Answers1

7

TL;DR If you always know the concrete type (e.g., kidney), then you don't need a type assertion; just pass it into your work variable and carry on--the compiler will guarantee that kidney satisfies the work interface, otherwise your program won't compile.

The reason you must first convert the concrete type into an interface{} is because type assertions (i.e., dynamic type checks) only make sense between dynamic types (i.e., interfaces). It doesn't make sense to do a runtime type check on a thing the compiler can guarantee at compile time. Hopefully this makes sense?

weberc2
  • 7,423
  • 4
  • 41
  • 57