Return different specialized implementations of interfaces from the same function

I have several data structures that are similar to some unique fields for each. All of them implement the same behavioral interface (DataPoint). Therefore, their processing can be performed once during the exchange of the type of each structure and work on it using the methods defined in the interface. I wanted the function to return an empty data structure for each type based on some criteria. However, I cannot compile this as if my function returns an interface by signature, but actually returns an implementation, it complains.

Here is a simplified example and an example of a playground, which I mean:

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)

}

As a result of compilation:

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)
+4
3

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.

+7

, getDataPoint DataPoint, : Create. , , , .

, DataPoint MetaData - . MetaData , .

+3

Your getDataPoint function returns an interface, not a structure. Therefore, if you want to use its return value as a structure, you must first perform a type statement. Here is the working code: https://play.golang.org/p/5lx4BLhQBg

+2
source

Source: https://habr.com/ru/post/1614301/