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

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


I’ve many knowledge constructions akin to :

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 take advantage of these structs this fashion:

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 purpose right here is later in my code, I’ll have a single operate that will probably be known as with []tableInfo as param to course of no matter knowledge within the desk tableInfo.tablename, utilizing the info construction in tableInfo.datastructure.

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

The rationale I need to go this fashion 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 permit direct conversion/task of slices of sure sort to []interface{} as defined right here: Ceaselessly Requested Questions (FAQ) – The Go Programming Language .

You will want 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 the same reply as you replied. It sort of defeats the aim of what I used to be going to strive. Inasmuch as I like Go, up to now (me, the Go beginner), I assume I nonetheless must unlearn some OOP ideas and study the GO approach.
From the FAQ you’ve supplied (how did I miss that ??), I perceive the explanation underlying this.

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

Thanks for the reply @ditchx !

You would additionally discover if generics would be just right for you:

https://gobyexample.com/generics

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

// Generic operate 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 strategy to circumvent the dearth of operate overloading in GO, am I proper ?

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

That is thrilling up to now; so many potentialities 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