Understanding the Error

Interface conversion errors occur when type assertions fail or types don't implement required interfaces:

``` panic: interface conversion: interface {} is nil, not string

panic: interface conversion: interface {} is int, not string

./main.go:15:10: cannot use &MyStruct literal (type *MyStruct) as type MyInterface: *MyStruct does not implement MyInterface (missing Method method) ```

Common Scenarios and Solutions

Scenario 1: Type Assertion on Nil Interface

Problem code: ``go func main() { var i interface{} // nil interface s := i.(string) // panic: interface conversion: interface {} is nil, not string fmt.Println(s) }

Solution - Use comma-ok idiom: ```go func main() { var i interface{}

s, ok := i.(string) if !ok { fmt.Println("Interface is not a string or is nil") return } fmt.Println(s) } ```

Safe assertion helper: ``go func safeString(i interface{}) string { if i == nil { return "" } s, ok := i.(string) if !ok { return "" } return s }

Scenario 2: Wrong Type in Assertion

Problem code: ```go func process(data interface{}) { s := data.(string) // panic if data is not a string fmt.Println(s) }

func main() { process(42) // panic: interface conversion: interface {} is int, not string } ```

Solution - Type switch: ``go func process(data interface{}) { switch v := data.(type) { case string: fmt.Println("String:", v) case int: fmt.Println("Int:", v) case float64: fmt.Println("Float:", v) case bool: fmt.Println("Bool:", v) default: fmt.Printf("Unknown type: %T\n", v) } }

Scenario 3: Interface Not Implemented

Problem code: ```go type Reader interface { Read([]byte) (int, error) }

type FileReader struct { path string }

func (f FileReader) Read(p []byte) (int, error) { // implementation return 0, nil }

func (f FileReader) Close() error { return nil }

func useReader(r Reader) {}

func useReadCloser(rc interface { Reader Close() error }) {}

func main() { f := FileReader{path: "/tmp/file"} useReader(f) // Works: FileReader implements Reader

fr := &FileReader{path: "/tmp/file"} useReader(fr) // Works: *FileReader also implements Reader

useReadCloser(f) // Works useReadCloser(fr) // Works } ```

When methods require pointer receiver: ```go type Writer interface { Write([]byte) (int, error) }

type Buffer struct { data []byte }

func (b *Buffer) Write(p []byte) (int, error) { b.data = append(b.data, p...) return len(p), nil }

func main() { var b Buffer // Value, not pointer var w Writer = b // Error: Buffer does not implement Writer

var w Writer = &b // Works: *Buffer implements Writer } ```

Why: Methods with pointer receivers are only accessible on pointers. Buffer doesn't have Write, only *Buffer does.

Scenario 4: Embedded Interface Conversion

Problem code: ```go type Reader interface { Read([]byte) (int, error) }

type Writer interface { Write([]byte) (int, error) }

type ReadWriter interface { Reader Writer }

func main() { var r Reader = getReader() rw := r.(ReadWriter) // panic: interface conversion: Reader does not contain Write } ```

Solution - Check before assertion: ```go func main() { var r Reader = getReader()

// Safe check if rw, ok := r.(ReadWriter); ok { rw.Write([]byte("hello")) } else { fmt.Println("Reader does not implement ReadWriter") } } ```

Scenario 5: Nil Inside Non-nil Interface

This is a subtle Go gotcha:

```go type MyInterface interface { Method() }

type MyStruct struct{}

func (m *MyStruct) Method() {}

func main() { var s *MyStruct = nil // nil pointer var i MyInterface = s // i is NOT nil!

fmt.Println(i == nil) // false! i.Method() // Works! Method called on nil receiver } ```

Explanation: An interface has two components: type and value. i has type *MyStruct and value nil, so i itself is not nil.

Solution - Handle nil interface correctly: ```go func isInterfaceNil(i interface{}) bool { if i == nil { return true } v := reflect.ValueOf(i) switch v.Kind() { case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan, reflect.Func, reflect.Interface: return v.IsNil() } return false }

func main() { var s *MyStruct = nil var i MyInterface = s

if isInterfaceNil(i) { fmt.Println("Interface contains nil value") } } ```

Safe Interface Patterns

Pattern 1: Defensive Function Parameters

```go func processString(s interface{}) (string, error) { if s == nil { return "", errors.New("nil value") }

str, ok := s.(string) if !ok { return "", fmt.Errorf("expected string, got %T", s) } return str, nil } ```

Pattern 2: Interface Guard at Compile Time

```go type MyInterface interface { DoSomething() }

// Compile-time check var _ MyInterface = (*MyStruct)(nil)

type MyStruct struct{}

func (m *MyStruct) DoSomething() {} ```

Pattern 3: Optional Interface Check

```go type Writer interface { Write([]byte) (int, error) }

type Flusher interface { Flush() error }

func writeAll(w Writer, data []byte) error { _, err := w.Write(data) if err != nil { return err }

// Optional: check if writer can flush if f, ok := w.(Flusher); ok { return f.Flush() } return nil } ```

Pattern 4: Unwrap for Errors

```go func main() { var err error

// Check for specific error type var pathErr *os.PathError if errors.As(err, &pathErr) { fmt.Printf("Path error: %s\n", pathErr.Path) }

// Check for specific error value if errors.Is(err, os.ErrNotExist) { fmt.Println("File does not exist") } } ```

Debugging Interface Issues

Print Type Information

```go func debugInterface(i interface{}) { if i == nil { fmt.Println("Interface is nil") return }

t := reflect.TypeOf(i) v := reflect.ValueOf(i)

fmt.Printf("Type: %v\n", t) fmt.Printf("Kind: %v\n", t.Kind()) fmt.Printf("Value: %v\n", v)

if t.Kind() == reflect.Ptr { fmt.Printf("Points to: %v\n", v.Elem()) }

// List methods fmt.Println("Methods:") for j := 0; j < t.NumMethod(); j++ { m := t.Method(j) fmt.Printf(" - %s\n", m.Name) } } ```

Check Interface Satisfaction

```go func implements(i interface{}, targetInterface interface{}) bool { targetType := reflect.TypeOf(targetInterface).Elem() actualType := reflect.TypeOf(i)

if actualType == nil { return false }

return actualType.Implements(targetType) }

// Usage var r io.Reader fmt.Println(implements(&bytes.Buffer{}, (*io.Reader)(nil))) // true ```

Verification

```bash # Compile and check go build ./...

# Run tests go test ./...

# Use static analysis go vet ./... staticcheck ./... ```