[NOOB Q] Passing around variable structures via functions

Hi All,

I’m just starting with Go after not touching real programming for a vastly long time. I’m trying to create a function where you pass in an integer and it returns a different struct based on that integer.
I’m not sure if this is even possible, and I’ve tried passing back pointers as well, and still no go. I’m getting a weird compilation error as well on that function that I don’t see why it’s failing.

The function would be called like so:

csvdata := csvinit(cmds.InPrecision)

Where the function ‘csvinit’ contains:
https://play.golang.org/p/_bQjKvnR9-n

I just need a hint here of what’s happening and how do I achieve what I need. Are functions even the right way of doing that? Should I be using methods or interfaces for that?

Thanks!

1 Like

What you want is not possible like that, you need to implement a common interface for both structs and use that interface type as return type.

I’m trying to avoid interfaces and methods, to keep things simple, because there’s going to be dozens of different structs.

Is it possible to do it through conversion?

Ie. convert the empty ‘csvdata’ struct into one of the filled ones?

You could use the empty interface and use typeguards. But to be honest, you really do not want that. At the end it will become unmaintainable.

Yeah, I’d rather avoid that.

I’ve tried conversion. Getting an error.
It doesn’t seem possible to just assign the pointer of one global struct to another either.
Something like: *csvdata{} := *CSVdataDB1{} doesn’t work.

I would have assumed conversion would work, something like this: https://play.golang.org/p/TixLZf2X5Eo

What about using the contents of a variable to initialize a struct? Is there a way to do something like this: https://play.golang.org/p/VQXd892Ku7y ?

Is there no easy way of doing it?

Ok, I have it working:
https://play.golang.org/p/FmwxItE1Bl4

But it drops all the tags. So now another problem. :sob::sob:

Nothing is dropped, the full result is as expected, it’s the zero value of that struct.

You’ll have a lot less trouble and you will fight the language a lot less, if you create a common interface or completely separate codepathes for dealing with each type.

Thanks Nobbz! Part of my problem seems that the reflection in the gocsv package I’ve been using is broken. So it can’t reflect back to the struct from the interface. Great learning experience though.

I’ll look at rewriting my code, as I drop the gocsv package… :stuck_out_tongue:

Nothing is broken, but reflection can’t see private fields, it will work when you export them using a capitalised field identifier.

I should probably clarify. I did get it working, but the gocsv package looses the struct tags. It’s the gocsv package that’s broken: https://github.com/gocarina/gocsv/issues/89

Which capitalized field identified do you mean?

I mean the field identifiers in your struct. You have them with lowercase names, so nothing from outside of your package can see the fields. You need to write them with a Capital letter to make them visible and accessible.

While that is correct, that’s not the issue here. The struct is read in, just not the tags.

You mean they are dropped then the CSV functions is using the struct? I have no experience with reading CSV with go but if it works in a similar way as Json for example must you use uppercase fieldnames so they are exported and another package can read them.

Yes, it’s similar, but the uppercase fieldnames made no difference, there’s a bug in the package.

Anyway, I used the CSVReader method directly from that package and forwent using their marshaling methods and the structs. It’s not as nice, but things are actually simpler that way anyway.

1 Like

I found one difference with your example and the example in the Readme off the package. In their call to the function they giva a slice of pointers but you send in just one structure. This could be the problem.


clients := []*Client{}

if err := gocsv.UnmarshalFile(clientsFile, &clients); err != nil { // Load clients from file
	panic(err)
}

then I read the code does the function used by Unmarshal function readTo start by finding the underlying type of the array or slice.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.