Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang multiple case in type switch

Tags:

go

when I run the code snippet bellow, it raise a error

a.test undefined (type interface {} is interface with no methods)

It seem the type switch does not take effect.

package main

import (
    "fmt"
)

type A struct {
    a int
}

func(this *A) test(){
    fmt.Println(this)
}

type B struct {
    A
}

func main() {
    var foo interface{}
    foo = A{}
    switch a := foo.(type){
        case B, A:
            a.test()
    }
}

If I change it to

    switch a := foo.(type){
        case A:
            a.test()
    }

it's ok now.

like image 762
yjfuk Avatar asked Nov 13 '16 14:11

yjfuk


1 Answers

This is normal behaviour that is defined by the spec (emphasis mine):

The TypeSwitchGuard may include a short variable declaration. When that form is used, the variable is declared at the beginning of the implicit block in each clause. In clauses with a case listing exactly one type, the variable has that type; otherwise, the variable has the type of the expression in the TypeSwitchGuard.

So, in fact, the type switch does take effect, but the variable a keeps the type interface{}.

One way you could get around this is to assert that foo has the method test(), which would look something like this:

package main

import (
    "fmt"
)

type A struct {
    a int
}

func (this *A) test() {
    fmt.Println(this)
}

type B struct {
    A
}

type tester interface {
    test()
}

func main() {
    var foo interface{}
    foo = &B{}
    if a, ok := foo.(tester); ok {
        fmt.Println("foo has test() method")
        a.test()
    }
}
like image 161
Tim Cooper Avatar answered Oct 02 '22 23:10

Tim Cooper