How do I use type switch on struct fields (when field is of interface type)?

huangapple go评论86阅读模式
英文:

How do I use type switch on struct fields (when field is of interface type)?

问题

请看:http://play.golang.org/p/GDCasRwYOp

我需要根据结构字段的类型来执行一些操作。

当字段是接口类型时,以下代码不起作用。

我知道为什么这不起作用。但是有没有办法实现我想要的效果?

package main

import (
    "fmt"
    "reflect"
)

type TT struct {
    Foo int
}

type II interface {
    Bar(int) (int, error)
}

type SS struct {
    F1 TT
    F2 II
}

func main() {
    var rr SS
    value := reflect.ValueOf(rr)
    for ii := 0; ii < value.NumField(); ii++ {
        fv := value.Field(ii)
        xv := fv.Interface()
        switch vv := xv.(type) {
        default:
            fmt.Printf("??: vv=%T,%v\n", vv, vv)
        case TT:
            fmt.Printf("TT: vv=%T,%v\n", vv, vv)
        case II:
            fmt.Printf("II: vv=%T,%v\n", vv, vv)
        }
    }
}
英文:

See: http://play.golang.org/p/GDCasRwYOp

I have a need to do things based on the type of the struct fields.

The following does not work when a field is of interface type.

I think I get why this is not working. But is there a way to do what I want to do?

package main

import (
    &quot;fmt&quot;
    &quot;reflect&quot;
)

type TT struct {
    Foo int
}

type II interface {
    Bar(int) (int, error)
}

type SS struct {
    F1 TT
    F2 II
}

func main() {
    var rr SS
    value := reflect.ValueOf(rr)
    for ii := 0; ii &lt; value.NumField(); ii++ {
        fv := value.Field(ii)
        xv := fv.Interface()
        switch vv := xv.(type) {
        default:
            fmt.Printf(&quot;??: vv=%T,%v\n&quot;, vv, vv)
        case TT:
            fmt.Printf(&quot;TT: vv=%T,%v\n&quot;, vv, vv)
        case II:
            fmt.Printf(&quot;II: vv=%T,%v\n&quot;, vv, vv)
        }
    }
}

答案1

得分: 5

或许这可以帮助你达到目标?

func main() {
    var rr SS
    typ := reflect.TypeOf(rr)
    TTType := reflect.TypeOf(TT{})
    IIType := reflect.TypeOf((*II)(nil)).Elem() // 是的,这很丑陋。

    for ii := 0; ii < typ.NumField(); ii++ {
        fv := typ.Field(ii)
        ft := fv.Type
        switch {
        case ft == TTType:
            fmt.Printf("TT: %s\n", ft.Name())
        case ft.Implements(IIType):
            fmt.Printf("II: %s\n", ft.Name())
        default:
            fmt.Printf("??: %s %s\n", ft.Kind(), ft.Name())
        }
    }
}
英文:

Maybe this gets you where you want to go?

func main() {
    var rr SS
    typ := reflect.TypeOf(rr)
    TTType := reflect.TypeOf(TT{})
    IIType := reflect.TypeOf((*II)(nil)).Elem() // Yes, this is ugly.
                   
    for ii := 0; ii &lt; typ.NumField(); ii++ {
        fv := typ.Field(ii)
        ft := fv.Type
        switch {   
        case ft == TTType:
            fmt.Printf(&quot;TT: %s\n&quot;, ft.Name())
        case ft.Implements(IIType):
            fmt.Printf(&quot;II: %s\n&quot;, ft.Name())
        default:
            fmt.Printf(&quot;??: %s %s\n&quot;, ft.Kind(), ft.Name())
        }
    }
}

huangapple
  • 本文由 发表于 2015年11月1日 09:07:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/33458247.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定