warvariuc
warvariuc

Reputation: 59674

Impossible type switch case

This program does not compile:

package main

type Validator struct {
}

// Error implements error interface
func (v *Validator) Error() string {
    return ""
}

func test() error {
    return &Validator{}
}

func main() {
    switch test().(type) {
    case nil:
        println("No error")
    case Validator:
        println("Validation error")
        return
    default:
        println("Unknown error")
        return
    }
}

The error is:

prog.go:19: impossible type switch case: test() (type error) cannot have dynamic type Validator (missing Error method)

But Validator struct has method Error.

Upvotes: 14

Views: 11559

Answers (2)

Ainar-G
Ainar-G

Reputation: 36249

The compiler is correct. Validator type does not implement Error, *Validator does. Validator and *Validator are different types. Just replace the former with the latter in the type switch:

switch test().(type) {
case nil:
    println("No error")
case *Validator:
    println("Validation error")
    return
default:
    println("Unknown error")
    return
}

Working example on the Go Playground: http://play.golang.org/p/aWqzPXweiA

Upvotes: 8

ANisus
ANisus

Reputation: 78055

You have two different types, Validator and the pointer type *Validator, and these two types have different method sets.

You have only defined an Error() method for the pointer while Validator doesn't have this method.

What you can do is the following change:

// Error implements error interface
func (v Validator) Error() string {
    return ""
}

...

case *Validator, Validator: // You are actually getting a *Validator

This implements Error() for both Validator and *Validator. As the Go specification says:

The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T)

Upvotes: 17

Related Questions