2016-11-07 2 views
-1

Мне нужна большая таблица структур, и мне нужно работать с возвращенной структурой.Golang return map [string] interface {} возвращающая переменная struct

package main 

import (
    "fmt" 
) 

var factory map[string]interface{} = map[string]interface{}{ 
    "Date":         Date{}, 
    "DateTime":        DateTime{}, 
} 

type Date struct { 
    year int //xsd:int Year (e.g., 2009) 
    month int //xsd:int Month (1..12) 
    day int //xsd:int Day number 
} 

func(d *Date) Init(){ 
    d.year = 2009 
    d.month = 1 
    d.day = 1 
} 

type DateTime struct { 
    date  Date //Date 
    hour  int //xsd:int 
    minute  int //xsd:int 
    second  int //xsd:int 
    timeZoneID string //xsd:string 
} 

func(d *DateTime) Init(){ 
    d.hour = 0 
    d.minute = 0 
    d.second = 0 

} 

func main() { 
    obj := factory["Date"] 
    obj.Init() 
    fmt.Println(obj) 

} 

Go Playground , но я получаю ошибку obj.Init неопределенного (типа интерфейса {} является интерфейс без методов) Есть ли способ сделать это?

ответ

2

В принципе, вам нужно сообщить компилятору, что все ваши типы (экземпляры на карте) всегда будут иметь метод Init. Для этого вы объявляете интерфейс с методом Init и строите карту этого интерфейса. Поскольку ваши ресиверы работают с указателем * xxx, вам нужно добавить указатели на объекты (а не сами объекты), добавив & перед ними.

package main 

import (
    "fmt" 
) 

type initializer interface { 
    Init() 
} 

var factory map[string]initializer = map[string]initializer{ 
    "Date":  &Date{}, 
    "DateTime": &DateTime{}, 
} 

type Date struct { 
    year int //xsd:int Year (e.g., 2009) 
    month int //xsd:int Month (1..12) 
    day int //xsd:int Day number 
} 

func (d *Date) Init() { 
    d.year = 2009 
    d.month = 1 
    d.day = 1 
} 

type DateTime struct { 
    date  Date //Date 
    hour  int //xsd:int 
    minute  int //xsd:int 
    second  int //xsd:int 
    timeZoneID string //xsd:string 
} 

func (d *DateTime) Init() { 
    d.hour = 0 
    d.minute = 0 
    d.second = 0 

} 

func main() { 
    obj := factory["Date"] 
    obj.Init() 
    fmt.Println(obj) 

}