MickeyThreeSheds
MickeyThreeSheds

Reputation: 1016

Can I use an interface as a parameter when writing a function which could end up being passed any kind of struct?

I am trying to write a function which could end up taking any kind of struct... let's say it is like this :

func setDate(s timestamp, data interface{}){
    data.Date = timestamp
}

I realize that I wouldn't need a function to set this value in real life, I am trying to learn more about how interfaces work, etc.

Upvotes: 0

Views: 50

Answers (1)

icza
icza

Reputation: 417472

You could approach it that way, but then inside setDate() you would need to use reflection to set the Date field. Go is a statically typed language, so if the (static) type of data is interface{} (which says nothing about it), you can't really do anything useful with it (you can't refer to its Date field, because there is no guarantee that its value has a Date field).

Instead you should define a HasDate interface which contains a single method:

type HasDate interface {
    SetDate(s time.Time)
}

The ability to set the date. And your function should expect a value of this interface type:

func setDate(s time.Time, data HasDate) {
    data.SetDate(s)
}

Anyone who implements this HasDate interface can be passed to your setDate() function. Note that in Go implementing interfaces is implicit: there is no declaration of intent. This means any type that has a SetDate(time.Time) method implements this HasDate interface without even knowing this interface exists.

This is an example type that implements it (more precisely its pointer *MyType):

type MyType struct {
    date time.Time
}

func (mt *MyType) SetDate(s time.Time) {
    mt.date = s
}

Example testing it (try it on the Go Playground):

mt := &MyType{}

setDate(time.Now(), mt)

fmt.Println(mt.date)

Upvotes: 5

Related Questions