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.
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)