type Verber interface {
	Func1()
	Func2() int
	...
}
 
type MyType int
 
// When implementing functions for an interface always use a pointer receiver function (unless you're never modifying state), since if even one function in the interface requires a pointer to modify state, then ALL of them will require pointers
func (m *MyType) Func1() {
	// do something
}
func (m *MyType) Func2() int {
	return m
}
 
// when creating an execute function always use pass by value, since this allows passing in a pointer AND a value, wheras a pointer type would ONLY allow passing in a pointer
func execute(v Verber) {
	v.Func1()
	fmt.Println(v.Func2())
}
 
func main() {
	m := MyType(1)
	
	// these are both allowed since we used a pass by value parameter in the execute function
	execute(m)
	execute(&m)
}
 

Accessing the underlying type

func checkType(v Verber) {
	if myType, ok := v.(MyType); ok {
		// v is implemented by MyType
	} else {
		// v is not implemented by MyType
	}
}