在编写可能最终被传递给任何类型的结构的函数时,可以将接口用作参数吗?

时间:2018-12-10 15:09:45

标签: go struct interface

我正在尝试编写一个函数,该函数最终可能采用任何类型的结构...可以说是这样的:

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

我意识到我并不需要在现实生活中设置此值的函数,而是尝试了解有关接口如何工作的更多信息,等等。

1 个答案:

答案 0 :(得分:5)

您可以采用这种方法,但是在setDate()内部,您需要使用反射来设置Date字段。 Go是一种静态类型的语言,因此,如果data的(静态)类型为interface{}(对此一无所知),您将无法对其真正有用(您无法引用)到其Date字段中,因为不能保证其值包含一个Date字段。

相反,您应该定义一个包含单个方法的HasDate接口:

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

设置日期的功能。并且您的函数应该期望此接口类型的值:

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

实现此HasDate接口的任何人都可以传递给您的setDate()函数。请注意,在Go中,实现接口是隐式的:没有意图的声明。这意味着任何具有SetDate(time.Time)方法的类型都将实现此HasDate接口,甚至不知道此接口存在。

这是实现它的示例类型(更确切地说是其指针*MyType):

type MyType struct {
    date time.Time
}

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

测试示例(在Go Playground上尝试):

mt := &MyType{}

setDate(time.Now(), mt)

fmt.Println(mt.date)