Understanding the Error

Go is a statically typed language. When types don't match, you'll see errors like:

bash
./main.go:10:15: cannot use myVar (type int) as type string
./main.go:15:22: cannot use user (type *User) as type User
./main.go:20:8: cannot use data (type interface{}) as type string: need type assertion
./main.go:25:10: cannot use s (type MyString) as type Stringer: MyString does not implement Stringer (missing String method)

Common Scenarios and Solutions

Scenario 1: Basic Type Conversion

Problem code: ``go func main() { var age int = 25 var message string = "Age is " + age // Error: cannot use age (type int) as type string fmt.Println(message) }

Solution - Explicit conversion: ``go func main() { var age int = 25 var message string = "Age is " + strconv.Itoa(age) fmt.Println(message) }

Common conversions: ```go // Int to string s := strconv.Itoa(42) s := fmt.Sprintf("%d", 42)

// String to int n, err := strconv.Atoi("42")

// Float to int n := int(3.14) // n = 3

// Int to float f := float64(42)

// Byte slice to string s := string([]byte{72, 101, 108, 108, 111})

// String to byte slice b := []byte("Hello") ```

Scenario 2: Pointer vs Value Type

Problem code: ```go type User struct { Name string }

func processUser(u User) { fmt.Println(u.Name) }

func main() { user := &User{Name: "Alice"} processUser(user) // Error: cannot use user (type *User) as type User } ```

Solution 1 - Dereference the pointer: ``go processUser(*user) // Pass a copy

Solution 2 - Modify function to accept pointer: ```go func processUser(u *User) { fmt.Println(u.Name) }

processUser(user) // Works ```

Solution 3 - Make function accept either: ```go func processUser(u User) { fmt.Println(u.Name) }

func main() { user := &User{Name: "Alice"} processUser(*user) // Dereference when calling // Or directUser := User{Name: "Bob"} processUser(directUser) } ```

Scenario 3: Interface Type Assertion

Problem code: ``go func main() { var i interface{} = "hello" var s string = i // Error: cannot use i (type interface{}) as type string fmt.Println(s) }

Solution - Type assertion: ```go func main() { var i interface{} = "hello"

// Unsafe assertion (panics if wrong type) s := i.(string) fmt.Println(s)

// Safe assertion with comma-ok idiom s, ok := i.(string) if ok { fmt.Println(s) } else { fmt.Println("Not a string") } } ```

Type switch for multiple types: ``go func describe(i interface{}) { switch v := i.(type) { case int: fmt.Printf("Integer: %d\n", v) case string: fmt.Printf("String: %s\n", v) case bool: fmt.Printf("Boolean: %t\n", v) default: fmt.Printf("Unknown type: %T\n", v) } }

Scenario 4: Interface Implementation

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

type MyWriter struct{}

func (w *MyWriter) Write(data []byte) (int, error) { return len(data), nil }

func useWriter(w Writer) {}

func main() { mw := MyWriter{} useWriter(mw) // Error: cannot use mw (type MyWriter) as type Writer } ```

Why this fails: The Write method is defined on *MyWriter, not MyWriter. So only *MyWriter implements Writer.

Solution 1 - Pass pointer: ``go func main() { mw := &MyWriter{} useWriter(mw) // Works }

Solution 2 - Define method on value: ```go func (w MyWriter) Write(data []byte) (int, error) { return len(data), nil }

func main() { mw := MyWriter{} useWriter(mw) // Now works } ```

Scenario 5: Custom Type Confusion

Problem code: ```go type ID int type UserID ID type ProductID ID

func getUser(id UserID) {}

func main() { var uid UserID = 1 var pid ProductID = 2

getUser(pid) // Error: cannot use pid (type ProductID) as type UserID } ```

Solution - Explicit conversion: ```go func main() { var uid UserID = 1 var pid ProductID = 2

getUser(uid) // Works getUser(UserID(pid)) // Explicit conversion } ```

Better design - use struct with type safety: ```go type UserID struct{ value int } type ProductID struct{ value int }

func NewUserID(v int) UserID { return UserID{value: v} } func (id UserID) Value() int { return id.value } ```

Scenario 6: Slice/Array Type Mismatch

Problem code: ``go func main() { var slice []int = []int{1, 2, 3} var array [3]int = slice // Error: cannot use slice (type []int) as type [3]int }

Solution - Copy elements: ```go func main() { slice := []int{1, 2, 3} array := [3]int{} copy(array[:], slice)

// Or use direct assignment array := [3]int{slice[0], slice[1], slice[2]} } ```

Generic Type Constraints (Go 1.18+)

Problem code: ```go func Sum[T int | float64](values []T) T { var total T for _, v := range values { total += v } return total }

func main() { Sum([]string{"a", "b"}) // Error: string does not satisfy int | float64 } ```

Solution - Use appropriate types: ``go func main() { Sum([]int{1, 2, 3}) // Works Sum([]float64{1.1, 2.2}) // Works }

Or expand the constraint: ```go type Number interface { int | int64 | float32 | float64 }

func Sum[T Number](values []T) T { var total T for _, v := range values { total += v } return total } ```

Debugging Type Issues

Use fmt.Printf with %T

go
func main() {
    var i interface{} = "hello"
    fmt.Printf("Type: %T, Value: %v\n", i, i)
    // Output: Type: string, Value: hello
}

Use reflect Package

```go import "reflect"

func main() { var x interface{} = []int{1, 2, 3}

fmt.Println("Type:", reflect.TypeOf(x)) fmt.Println("Kind:", reflect.TypeOf(x).Kind()) fmt.Println("Value:", reflect.ValueOf(x))

// Check if type implements an interface t := reflect.TypeOf(x) writerType := reflect.TypeOf((*Writer)(nil)).Elem() fmt.Println("Implements Writer:", t.Implements(writerType)) } ```

Compile-Time Interface Check

go
var _ Writer = (*MyWriter)(nil) // Compile error if *MyWriter doesn't implement Writer

Verification

```bash # Check types at compile time go build ./...

# Use go vet for common type issues go vet ./...

# Use staticcheck for deeper analysis go install honnef.co/go/tools/cmd/staticcheck@latest staticcheck ./... ```