In Go Programming Language, we will use interface very often. And sometimes, there are some struct that implemented more than one interface.

An example:

type Model interface {
	PrimaryKey() string
}

type SecretModel interface {
	GetUnexportedField() []string
}

type exModel struct {
	ID uint
	Name string
	CreatedAt time.Time
}

func (exModel) GetPrimaryKey() string {
	return "ID"
}

func (exModel) GetUnexportedField() []string {
	return []string{"CreatedAt"}
}

type otherModel struct {
	ID uint
	Name string
	Description string
	CreatedAt time.Time
}

func (otherModel) GetPrimaryKey() string {
	return "ID"
}

As you can see, the exModel implement two interfaces and otherModel just implemented one interface.

And then, i have this kind of method to build data from model, exporting field and it’s value if it’s not secret field (implement secretmodel).

func exportData(model Model) map[string]interface{} {
	return ...
}

In my export data function, i simply put the Model interface as parameter. Of course, i need to check the model if it’s implement secret model as well.

As the very simple solution is using type assertion, but we can use reflect too.

func exportData(model Model) map[string]interface{} {
	if secretmodel, ok := model.(secretModel); ok {
		for _, unexportedField := range secretmodel.GetUnexportedField() {
			// ...
		}
	}
	return ...
}

From the above example, we can assume that type assertion in Go has multiple return value. First, it’s new value and the second is the boolean expression that tells us if the type assertion was succed or failed.