说我有3种结构:
type A struct{
Foo map[string]string
}
type B struct{
Foo map[string]string
}
type C struct{
Foo map[string]string
}
然后我想创建一个可以接受任何这些结构的函数:
func handleFoo (){
}
使用Golang有什么办法吗?像这样:
type ABC = A | B | C
func handleFoo(v ABC){
x: = v.Foo["barbie"] // this would be nice!
}
好,让我们尝试一个界面:
type FML interface {
Bar() string
}
func handleFoo(v FML){
z := v.Bar() // this will compile
x: = v.Foo["barbie"] // this won't compile - can't access properties like Foo from v
}
用一种鼓励/强迫合成的语言,我无法理解为什么您无法访问Foo之类的属性。
答案 0 :(得分:3)
您可以通过这种方式使用接口,添加方法class C(A):
def __init__(self):
super(C, self).__init__()
print(self.p1)
以获取每个结构的foo。
print(A().p1)
B('modified')
C()
答案 1 :(得分:2)
由于A,B和C都assignable属于相同的基础类型,因此可以使用带有该基础类型的参数的函数:func handleFoo(v struct{ Foo map[string]string })
此方法的局限性在于handleFoo
中不提供关于A,B和C的方法(即使具有相同的名称和签名)。
答案 2 :(得分:1)
您可以尝试reflect
并将interface{}
传递给handleFoo
https://play.golang.org/p/sLyjDvVrUjQ
https://golang.org/pkg/reflect/
package main
import (
"fmt"
"reflect"
)
func main() {
type A struct {
Foo map[string]string
}
type B struct {
Foo map[string]int
}
type C struct {
Foo map[string]uint
}
a := A{
Foo: map[string]string{"a":"1"},
}
b := B{
Foo: map[string]int{"a":2},
}
c := C {
Foo: map[string]uint{"a":3},
}
fmt.Println(a, b, c)
handleFoo(a)
handleFoo(b)
handleFoo(c)
fmt.Println(a, b, c)
}
func handleFoo(s interface{}) {
v := reflect.ValueOf(s)
foo := v.FieldByName("Foo")
if !foo.IsValid(){
fmt.Println("not valid")
return
}
switch foo.Type() {
case reflect.TypeOf(map[string]string{}):
fmt.Println("is a map[string]string")
foo.Interface().(map[string]string)["a"] = "100"
case reflect.TypeOf(map[string]int{}):
fmt.Println("is a map[string]int")
foo.Interface().(map[string]int)["a"] = 200
case reflect.TypeOf(map[string]uint{}):
fmt.Println("is a map[string]uint")
foo.Interface().(map[string]uint)["a"] = 300
}
}