There is no simple way, alas.
This is due to the fact that [] interface {} (slice of interfaces)! = [] Object (slice of Objects)! = [] IDer (slice of interface IDer). These structures are displayed differently in memory - so the compiler refuses to do these implicit conversions automatically.
You can, of course, every time obviously force it to do
arr := make([]IDer, len(arr1)) for i := range arr1 { arr[i] = IDer(arr1[i]) }
but ugly and eats memory.
Reading your question, I thought about what you want to do inside searchDiff. Already from the question itself suggests the conclusion that you want to determine the behavior , but not the behavior of the elements, namely the behavior of the slice elements. And idiomatic behavior is set via interfaces.
Option 1
We define types:
type IDer interface { ID() int } // Object implements IDer func (obj *Object) ID() int { return obj.Id }
And Slice Interfaces IDer
type IDerSlice []IDer
Then your searchDiff function is defined as
func (diff *difference) searchDiff(arr1, arr2 IDerSlice) { for i := range arr1 { for j := range arr2 { if arr1[i].ID() < arr2[j].ID() { //... } } } }
Everything, you can work. https://play.golang.org/p/gnTnf23973
package main import () type difference struct{} type Object struct { Id int `xml:"id,attr"` Name string `xml:"name,attr"` Address string `xml:"address,attr"` Code string `xml:"code,attr"` } type IDer interface { ID() int } // Object implements IDer func (obj *Object) ID() int { return obj.Id } type IDerSlice []IDer func (diff *difference) searchDiff(arr1, arr2 IDerSlice) { for i := range arr1 { for j := range arr2 { if arr1[i].ID() < arr2[j].ID() { //... } } } } func main() { // ΠΠ±ΡΠ°ΡΠΈΡΡ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡΡΠΎ ΡΠΎΠ·Π΄Π°Π΅ΠΌ ΠΌΡ ΠΈΠΌΠ΅Π½Π½ΠΎ IDerSlice arr1 := IDerSlice{ &Object{ Id: 1, Name: "object1", Address: "earth", Code: "er", }, &Object{ Id: 2, Name: "object2", Address: "moon", Code: "mn", }, } arr2 := IDerSlice{ &Object{ Id: 10, Name: "object10", Address: "mars", Code: "mr", }, &Object{ Id: 11, Name: "object11", Address: "phobos", Code: "ph", }, &Object{ Id: 12, Name: "object12", Address: "deimos", Code: "de", }, } diff := &difference{} diff.searchDiff(arr1, arr2) }
Notice that we create slices of objects exactly as IDerSlice, those as a collection of elements with which we want to work uniformly through the interface. Therefore, all data from the underlying structures will have to be proxied by getters and setters to this interface, which is inconvenient, but this is exactly what you wanted - uniform work with different data structures through behavior.
Option 2
If you only have slices of objects of the type you need, you will have to do it as done in the sort package. https://play.golang.org/p/e5Dt7-Ocnx
package main import ( //"fmt" ) type difference struct{} type Object struct { Id int `xml:"id,attr"` Name string `xml:"name,attr"` Address string `xml:"address,attr"` Code string `xml:"code,attr"` } type Object2 struct { Id int `xml:"id,attr"` Name2 string `xml:"name,attr"` Address2 string `xml:"address,attr"` Code2 string `xml:"code,attr"` } type searchDiffInterface interface { Len() int GetID(i int) int } type ObjectSlice []*Object type Object2Slice []*Object2 func (obj ObjectSlice) GetID(i int) int { return obj[i].Id } func (obj ObjectSlice) Len() int { return len(obj) } func (obj Object2Slice) GetID(i int) int { return obj[i].Id } func (obj Object2Slice) Len() int { return len(obj) } func (diff *difference) searchDiff(arr1, arr2 searchDiffInterface) { for i := 0; i < arr1.Len(); i++ { for j := 0; j < arr2.Len(); j++ { if arr1.GetID(i) == arr2.GetID(j) { //... } } } } func main() { arr1 := []*Object{ &Object{ Id: 1, Name: "object1", Address: "earth", Code: "er", }, &Object{ Id: 2, Name: "object2", Address: "moon", Code: "mn", }, } arr2 := []*Object2{ &Object2{ Id: 10, Name2: "object10", Address2: "mars", Code2: "mr", }, &Object2{ Id: 11, Name2: "object11", Address2: "phobos", Code2: "ph", }, &Object2{ Id: 12, Name2: "object12", Address2: "deimos", Code2: "de", }, } diff := &difference{} // ΠΠ±ΡΠ°ΡΠΈ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡΠ²Π½ΠΎΠ΅ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠΎΠ² ΡΠ΅ΠΏΠ΅ΡΡ ΡΡΡ diff.searchDiff(ObjectSlice(arr1), Object2Slice(arr2)) }
Whichever approach you choose, you have to explicitly type somewhere. Predefine searchDiffInterface with all the methods you need in searchDiff.
If they are all the same for you, or are very similar, then you can use code generation using go generate or a trick similar to sort.Reverse.
And in the end, the variant is in reflect (with automatic type conversion), but it is terribly slow.
func (diff *difference) searchDiff(arr1, arr2 interface{}) { arr1slice := reflect.ValueOf(arr1) arr2slice := reflect.ValueOf(arr2) for i := 0; i < arr1slice.Len(); i++ { for j := 0; j < arr2slice.Len(); j++ { val_arr1i := arr1slice.Index(i) val_arr2j := arr2slice.Index(j) arr1id := val_arr1i.Elem().FieldByName("Id") arr2id := val_arr2j.Elem().FieldByName("Id") fmt.Println(val_arr1i.Elem(), val_arr2j.Elem()) if arr1id == arr2id { //... } } } }