从Go lang中的同一函数返回不同的接口专用实现

时间:2015-11-03 15:50:25

标签: go interface

我有一些数据结构,每个数据结构都有一些独特的字段。它们都实现了相同的行为接口(DataPoint)。 因此,他们的处理可以在交换每个结构的类型并通过界面中定义的方法对其进行操作时完成一次。我希望有一个函数根据某些条件返回每种类型的空数据结构。 但是,我似乎无法编译它,好像我的函数通过签名返回接口但实际上返回一个实现,它抱怨。

以下是我的意思的简化示例和游乐场示例:

https://play.golang.org/p/LxY55BC59D

package main

import "fmt"


type DataPoint interface {
    Create() 
}

type MetaData struct {
    UniqueId string
    AccountId int
    UserId int
}

type Conversion struct {
    Meta MetaData
    Value int
}

func (c *Conversion) Create() {
    fmt.Println("CREATE Conversion")
}

type Impression struct {
    Meta MetaData
    Count int
}

func (i *Impression) Create() {
    fmt.Println("CREATE Impression")
} 

func getDataPoint(t string) DataPoint {
    if t == "Conversion" {
        return &Conversion{}
    } else {
        return &Impression{}
    }
}



func main() {
    meta := MetaData{
        UniqueId: "ID123445X",
        AccountId: 1,
        UserId: 2,
    }
    dpc := getDataPoint("Conversion")
    dpc.Meta = meta
    dpc.Value = 100
    dpc.Create()

    fmt.Println(dpc)

    dpi :=  getDataPoint("Impression")
    dpi.Meta = meta
    dpi.Count = 42
    dpi.Create()

    fmt.Println(dpi)

}

汇编产生:

prog.go:51: dpc.Meta undefined (type DataPoint has no field or method Meta)
prog.go:52: dpc.Value undefined (type DataPoint has no field or method Value)
prog.go:58: dpi.Meta undefined (type DataPoint has no field or method Meta)
prog.go:59: dpi.Count undefined (type DataPoint has no field or method Count)

3 个答案:

答案 0 :(得分:7)

如果没有type assertion,您就无法访问此类字段。您只能在界面上调用方法,它对其实现细节一无所知。如果确实需要访问这些字段,请使用类型断言:

dpc := getDataPoint("Conversion")
dpc.(*Conversion).Meta = meta
dpc.(*Conversion).Value = 100
dpc.Create()

dpi := getDataPoint("Impression")
dpi.(*Impression).Meta = meta
dpi.(*Impression).Count = 42
dpi.Create()

游乐场:https://play.golang.org/p/Ije8hfNcWS

答案 1 :(得分:3)

您的问题是getDataPoint的结果是DataPoint,只有一种方法可用:Create。然后尝试将其用作特定的结构类型,偶然提供所有元数据字段。

您可以让DataPoint接口提供MetaData功能或类似功能,或者在字段上提供单独的getter。如果MetaData类型实现了这些方法,那么当它们作为接口本身呈现时,它们将从任一特定结构中可用。

答案 2 :(得分:2)

你的函数getDataPoint返回一个接口,而不是一个struct。因此,如果要将其返回值用作结构,则必须首先执行类型断言。这是一个有效的代码: https://play.golang.org/p/5lx4BLhQBg