Storing types in a map[string]type ?

3,147 views
Skip to first unread message

jakdept

unread,
Dec 14, 2017, 9:20:05 PM12/14/17
to golang-nuts
I'm writing a utility to import/export data into an API. I'd like to be able to accept multiple input/output formats, and support multiple commands. I was going to use kingpin for the flags/commands, and do a type format after that.

My plan was to declare an interface with the methods I'm going to use, a struct that's got the parameters needed for the interface, but doesn't satisfy it, and declare a map of structs that do satisfy that interface.

type versionParams struct {
 options
int
 sess    api
.Session
 
in      io.ReadCloser
 
out     io.WriteCloser
 log    
*log.Logger
}


type
Version interface {
 
Import()
 
Export()
 
Example()
}


var versions map[string]Version

In main, I'd detect the actions, and if it's one of the actions for one of those types, create the object, load it up with input and output and stuff. Note, because of the flags I'm using, *format is a pointer to a string holding the format's name. So, I was thinking I'd do something like:

args := versionParams{}


// some stuff to fill in the args


args
.(versions[*format]).Import()
 
Then, for each version I want to add, in that version I'd do something like the following, in it's own file:

type v1csv struct {
 versionParams
 
Version
}


func init
() {
 versions
["v1csv"] = v1csv
}


func
(v *v1csv) Import() {
// do stuff
}


func
(v *v1csv) Example() {
// do stuff
}


func
(v *v1csv) Export() {
// do stuff
}

I don't think this works for multiple reasons though. I don't think you can declare a map of types that satisfy an interface like that? And once you do, I guess I don't know if I can cast/convert from one struct to another without directly naming the struct...? I guess I could drop the generic versionParams struct and just create structs for each type, but I would still want to put those struct types into a map - that's the part that I'm stuck on figuring out.

I wanted to go with something like this layout specifically so that I could add new formats by simply adding that one format in a self contained file. I don't want to statically name them and 

Mostly, I think I'm just lost in design and I cannot see the way out myself. Any suggestions to help me figure out how to do this, or something more appropriate, would be appreciated. :-)
Message has been deleted

jakdept

unread,
Dec 15, 2017, 11:20:28 AM12/15/17
to golang-nuts
So, I've thought about this further - if I don't bother with the interfaces, I can make this simpler. I can convert between with just v1csv(object) just fine. And that . should work because it'll only be used in a client, and it should still be extendable.

It would still be nice to store those struct types in an array/map somehow. And that's the part where I'm still stuck. :/

Sebastien Binet

unread,
Dec 15, 2017, 11:54:25 AM12/15/17
to jakdept, golang-nuts
On Fri, Dec 15, 2017 at 5:20 PM, jakdept <jak...@gmail.com> wrote:
So, I've thought about this further - if I don't bother with the interfaces, I can make this simpler. I can convert between with just v1csv(object) just fine. And that . should work because it'll only be used in a client, and it should still be extendable.

It would still be nice to store those struct types in an array/map somehow. And that's the part where I'm still stuck. :/

you can do something like that:


ie: register constructor functions for the different types.
the advantage is that you can pass state or arguments to these constructor functions.

if you don't need state, or if the zero value of your types will *always* be sufficient, then, this could work for you:

(I would go with the former version instead of the latter: it's more explicit and doesn't involve reflect as much)

hth,
-s

Reply all
Reply to author
Forward
0 new messages