Question: Is there a way to change between types?

Hi,
I have 4 slices of structures:

type IO1b_t []struct {
    ID uint8
    Val uint8
}

type IO2b_t []struct {
    ID uint8
    Val uint16
}

type IO4b_t []struct {
    ID uint8
    Val uint32
}

type IO8b_t []struct {
    ID uint8
    Val uint64
}

I want to implement Stringer interface for both types. The body of String() is identical:

 var str string
    for _,value := range rec {
        str += fmt.Sprintf("ID:%d, Value:%d")
    }
    return str

Is it possible to implement one function for both receivers? The example would be like this:

 funct (io IO1b_t) String() string {
        getIoFormatString(io)
    }

    funct (io IO2b_t) String() string {
        getIoFormatString(io)
    }

    funct (io IO4b_t) String() string {
        getIoFormatString(io)
    }

    funct (io IO8b_t) String() string {
        getIoFormatString(io)
    }

    funst getIoFormatString(rec interface{}) string {
        var str string
        for _,value := range rec {
            str += fmt.Sprintf("ID:%d, Value:%d")
        }
        return str
    }

Is it possible to do something like this? If so, how? Of course, I can implement the some method body for all methods, but I thought that there has to be a better way. I would like to have only one fmt.Sprintf() function for efficiency.

Thanks.

Hey @Deimis, you probably want a type switch if I understand your question correctly:

package main

import "fmt"

type MyObjOne struct {
	id  int
	val int
}
type MyObjTwo struct {
	id  int
	val int
}

func ObjectOutput(obj interface{}) string {
	switch o := obj.(type) {
	case MyObjOne:
		return fmt.Sprintf("MyObjOne, id: %d, val %d", o.id, o.val)
	case MyObjTwo:
		return fmt.Sprintf("MyObjTwo, id: %d, val %d", o.id, o.val)
	}
	return ""
}

func main() {
	m1 := MyObjOne{1, 2}
	m2 := MyObjTwo{3, 4}

	fmt.Println(ObjectOutput(m1))
	fmt.Println(ObjectOutput(m2))
}

Perhaps fmt.Printf("%#v", …) Would be good enough for you use case.

1 Like

Thank you for your answers. But I have something else in mind :slight_smile: I Want to print array of structures:
type IO1b_t **[]**struct {
ID uint8
Val uint8
}

type IO2b_t **[]**struct {
ID uint8
Val uint16
}
And I do not known how to do for cycle:
for _,value := range rec // rec is interface that gets struct array.

Hey @Deimis, do you mean like this, because type switches are pretty awesome:

package main

import "fmt"

type MyObjOne []struct {
	id  int
	val int
}
type MyObjTwo []struct {
	id  int
	val int
}

func OutputObject(obj interface{}) string {
	var str string

	switch o := obj.(type) {
	case MyObjOne:
		for _, mo1 := range o {
			str += fmt.Sprintf("MyObjOne, id: %d, val %d\n", mo1.id, mo1.val)
		}
	case MyObjTwo:
		for _, mo2 := range o {
			str += fmt.Sprintf("MyObjTwo, id: %d, val %d\n", mo2.id, mo2.val)
		}
	}

	return str
}

func main() {
	m1 := MyObjOne{
		{1, 2},
		{3, 4},
	}
	m2 := MyObjTwo{
		{5, 6},
		{7, 8},
	}

	fmt.Println(OutputObject(m1))
	fmt.Println(OutputObject(m2))
}

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