Wednesday, October 5, 2022
HomeGolangPassing slices of structs as empty interfaces to a perform - Getting...

Passing slices of structs as empty interfaces to a perform – Getting Assist


I’ve many information constructions resembling :

sort dbClusters struct {
  some struct members
}

sort dbHostStates struct {
  some struct members
}

And one other struct outlined as such:

sort tableInfo struct {
  tablename string
  datastructure []interface{}
}

Someplace in my code, I exploit these structs this manner:

func myFunc() {
  var clusters []dbClusters
  var states []dbHostStates

  [some code to populate the structs]

  tables := tableInfo {
    tableInfo { tablename: "clusterstable", datastructure: clusters },
    tableInfo { tablename: "statestable", datastructure: states }
  }
}

The aim right here is later in my code, I’ll have a single perform that shall be known as with []tableInfo as param to course of no matter information within the desk tableInfo.tablename, utilizing the information construction in tableInfo.datastructure.

I assumed that having that data in a struct tableInfo was the right approach, and utilizing an empty interface to map with the precise information construction was “intelligent”.

The rationale I need to go this manner is that I may need as 15 tables to deal with, I don’t want to duplicate the near-same code 15 occasions.

What I’m lacking or misunderstanding right here ?

Attempting to construct, I get this:

[21:43:58|jfgratton@bergen:source]: ./construct.sh 
# vmman3/db
db/db-import.go:47:54: can't use hyps (variable of sort []dbHypervisors) as sort []interface{} in struct literal
db/db-import.go:48:55: can't use sps (variable of sort []dbStoragePools) as sort []interface{} in struct literal
db/db-import.go:49:50: can't use vms (variable of sort []dbVmStates) as sort []interface{} in struct literal

I perceive what it says, not why it says so.

Hello!

Golang doesn’t enable direct conversion/project of slices of sure sort to []interface{} as defined right here: Continuously Requested Questions (FAQ) – The Go Programming Language .

You will have to transform to []interface{} first earlier than assigning it to datastructure.

func myFunc() {
  var clusters []dbClusters
  var states []dbHostStates

  [some code to populate the structs]

  dbC := make([]interface{}, len(clusters))
  for i, v := vary clusters {
    dbC[i] = v
  }

  dbS := make([]interface{}, len(states))
  for i, v := vary states {
    dbS[i] = v
  }

  tables := tableInfo {
    tableInfo { tablename: "clusterstable", datastructure: dbC },
    tableInfo { tablename: "statestable", datastructure: dbS }
  }
}

I’ve discovered an identical reply as you replied. It type of defeats the aim of what I used to be going to strive. Inasmuch as I like Go, thus far (me, the Go beginner), I suppose I nonetheless should unlearn some OOP ideas and be taught the GO approach.
From the FAQ you’ve offered (how did I miss that ??), I perceive the rationale underlying this.

This implies then that I’ll some code near-duplication for each desk I’ve to undergo, then. I wished to construct some type of TableInjectorFactory() perform, however …

Thanks for the reply @ditchx !

You might additionally discover if generics would give you the results you want:

https://gobyexample.com/generics

Easiest way to make use of generics to take away duplication your code is to make use of a generic perform which converts your slices to []interface{}. The code will now look one thing like:

// Generic perform to transform slices of any sort to []interface{}
func dataStructure[T any](s []T) []interface{} {
	ds := make([]interface{}, len(s))
	for i, v := vary s {
		ds[i] = v
	}

	return ds
}

func myFunc() {
  var clusters []dbClusters
  var states []dbHostStates

  [some code to populate the structs]

  dbC := dataStructure[dbClusters](clusters)
  dbS := dataStructure[dbHostStates](states)

  tables := tableInfo {
    tableInfo { tablename: "clusterstable", datastructure: dbC },
    tableInfo { tablename: "statestable", datastructure: dbS }
  }
}

My understanding of generics is that it’s a approach to circumvent the shortage of perform overloading in GO, am I proper ?

I intend to look that one up within the subsequent iteration of my software program. This mission is my “studying” mission (a Python3 to GO port of a QEMU vm supervisor).

That is thrilling thus far; so many prospects with GO…

Bookmarked your hyperlink, will certainly look it up quickly. I need to get this iteration of my software program out of the door ASAP, then refine it.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments