英文:
type A satisfying requirements of type B
问题
我对一个数据类型/结构能否满足函数调用中所期望的另一个类型的要求有一个问题。
在一个用Go语言编写的RSS和Atom feed处理程序的feed.go文件中,有一个New辅助函数,它将一个ChannelHandlerFunc作为第三个参数,你可以看到它作为参数传递给了NewDatabaseChannelHandler,而NewDatabaseChannelHandler返回一个DatabaseHandler,如下所示。DatabaseHandler中嵌入了一个ChannelHandler。你可以在New函数中看到NewDatabaseChannelHandler的返回值(即DatabaseHandler)作为第三个参数传递给了NewWithHandlers。然而,正如你所看到的,NewWithHandlers需要一个ChannelHandler作为第三个参数。
问题:为什么当NewWithHandlers将NewDatabaseChannelHandler的返回值(即DatabaseHandler)作为第三个参数传递时,不会抛出错误。NewWithHandlers期望的是一个ChannelHandler而不是一个DatabaseHandler?
func New(cachetimeout int, enforcecachelimit bool, ch ChannelHandlerFunc, ih ItemHandlerFunc) *Feed {
    db := NewDatabase()
    f := NewWithHandlers(cachetimeout, enforcecachelimit, NewDatabaseChannelHandler(db, ch), NewDatabaseItemHandler(db, ih))
    f.database = db
    return f
}
然后,NewWithHandlers接受一个ChannelHandler作为第三个参数。
// NewWithHandler creates a new feed with handlers
// People should use this approach from now on
func NewWithHandlers(cachetimeout int, enforcecachelimit bool, ch ChannelHandler, ih ItemHandler) *Feed {
    v := new(Feed)
    v.CacheTimeout = cachetimeout
    v.EnforceCacheLimit = enforcecachelimit
    v.Type = "none"
    v.channelHandler = ch
    v.itemHandler = ih
    return v
}
这个file是NewDatabaseChannelHandler的源代码。
然而,NewDatabaseChannelHandler并不返回一个ChannelHandler,它返回一个DatabaseHandler。
func NewDatabaseChannelHandler(db *database, chanhandler ChannelHandler) ChannelHandler {
    database := new(databaseHandler)
    database.db = db
    database.chanhandler = chanhandler
    return database
}
type databaseHandler struct {
    db          *database
    itemhandler ItemHandler
    chanhandler ChannelHandler
}
英文:
I have a question about a data type/structure being able to satisfy the requirements of another type that's expected in a function call.
In feed.go of an RSS and Atom feed handler written in Go, there is a New helper function that takes a ChannelHandlerFunc as a third argument, which you can see gets passed as a parameter to a NewDatabaseChannelHandler, which returns a DatabaseHandler, as you can see below. A DatabaseHandler has a ChannelHandler embedded in it. You can see in the New function that the return value  of NewDatabaseChannelHandler (i.e. the DatabaseHandler) gets passed as the 3rd parameter to NewWithHandlers. However, NewWithHandlers as you can see, requires a ChannelHandler as the third parameter.
Question: Why doesn't NewWithHandlers throw an error when it's passed the DatabaseHandler as a return value from NewDatabaseChannelHandler as a third parameter. NewWithHandlers expects a ChannelHandler not a DatabaseHandler?
func New(cachetimeout int, enforcecachelimit bool, ch ChannelHandlerFunc, ih ItemHandlerFunc) *Feed {
	db := NewDatabase()
	f := NewWithHandlers(cachetimeout, enforcecachelimit, NewDatabaseChannelHandler(db, ch), NewDatabaseItemHandler(db, ih))
	f.database = db
	return f
}
then NewWithHandlers accepts a ChannelHandler as a third argument
// NewWithHandler creates a new feed with handlers
// People should use this approach from now on
func NewWithHandlers(cachetimeout int, enforcecachelimit bool, ch ChannelHandler, ih ItemHandler) *Feed {
	v := new(Feed)
	v.CacheTimeout = cachetimeout
	v.EnforceCacheLimit = enforcecachelimit
	v.Type = "none"
	v.channelHandler = ch
	v.itemHandler = ih
	return v
}
This file is the source code for the NewDatabaseChannelHandler
However, NewDatabaseChannelHandler doesn't return a ChannelHandler, it returns a DatabaseHandler
func NewDatabaseChannelHandler(db *database, chanhandler ChannelHandler) ChannelHandler {
	database := new(databaseHandler)
	database.db = db
	database.chanhandler = chanhandler
	return database
}
type databaseHandler struct {
	db          *database
	itemhandler ItemHandler
	chanhandler ChannelHandler
}
答案1
得分: 1
DatabaseHandler通过以下方法满足ChannelHandler接口:
func (d *databaseHandler) ProcessChannels(f *Feed, ch []*Channel)
该接口要求:
type ChannelHandler interface {
    ProcessChannels(f *Feed, newchannels []*Channel)
}
英文:
The DatabaseHandler satisfies the ChannelHandler interface with this method:
func (d *databaseHandler) ProcessChannels(f *Feed, ch []*Channel)
The interface requires:
type ChannelHandler interface {
	ProcessChannels(f *Feed, newchannels []*Channel)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论