如何从用作泛型的接口访问struct属性

时间:2018-10-05 10:02:39

标签: go

也许我刚刚使我的代码复杂化了,但是我试图更好地理解接口和结构在golang中的工作方式。

基本上,我在哈希表中存储满足接口I的元素。由于所有满足我条件的项目都可以包含在I元素内,因此我认为我可以将I用作一种“通用”接口,将它们填充在哈希图中,然后将其拉出并访问“ underlyng”结构方法从那里。

不幸的是,在拔出元素之后,我发现我无法调用struct方法,因为元素属于Interface类型,并且“原始”结构不再可用。

有没有一种方法可以使对满足我的结构的访问变得干净而简单?

这是我的代码,它在for循环内抛出“ value.name未定义(类型I没有字段或方法名)”:

/**
 * Define the interface
 */
type I interface{
    test()
}

/**
 * Define the struct
 */
type S struct{
    name string
}

/**
 *  S now implements the I interface
 */
func (s S) test(){}

func main(){

    /**
     * Declare and initialize s S
     */
    s := S{name:"testName"}

    /**
     * Create hash table
     * It CAN contains S types as they satisfy I interface
     * Assign and index to s S
     */
    testMap := make(map[string]I)
    testMap["testIndex"] = s

    /**
     * Test the map length
     */
    fmt.Printf("Test map length: %d\r\n", len(testMap))

    for _, value := range testMap{

        /**
         * This is where the error is thrown, value is of Interface type, and it is not aware of any "name" property
         */
        fmt.Printf("map element name: %s\r\n", value.name)
    }

}

2 个答案:

答案 0 :(得分:1)

您应该在界面中添加访问器:

type I interface {
    test()
    Name() string
}

然后确保您的结构体实现了此方法:

func (s S) Name() string {
    return s.name
}

然后使用访问器方法访问名称:

        fmt.Printf("map element name: %s\r\n", value.Name())

答案 1 :(得分:0)

我认为您需要的是type swithes,就像tour of go

您可以访问下面的基础结构:

for _, value := range testMap {
    switch v := value.(type) {
    case S:
        fmt.Printf("map element name: %s\r\n", v.name)
        // TODO: add other types here
    }
}