当将对象传递并在interface{}中捕获时,无法访问函数。

huangapple go评论93阅读模式
英文:

Can't access function when passing object and catching it in a interface{}

问题

这是我尝试做的事情:

package products

ProductManager struct {
    products []*Product
    index    int64
}

func NewPM() *ProductManager {
    return &ProductManager{}
}

func (p *ProductManager) List() []*Product {
    return p.products
}

---

var productManager = products.NewPM()

func main() {
    api := Api{}
    api.Attach(productManager, "/products")
}

func (api Api) Attach(rm interface{}, route string) {
    // 将典型的 REST 操作应用到 Mux。
    // 例如:Product - 对应 /products
    mux.Get(route, http.HandlerFunc(index(rm)))
}

func index(rm interface{}) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // allRecords := rm.List() - 无法调用。找不到方法。
        result := reflect.TypeOf(rm) // 可以工作,显示正确的类型。
        method := result.Method(0).Name // 也可以工作!显示类型上的一个函数。
        w.Write([]byte(fmt.Sprintf("%v", method)))
    }
}

为什么我无法在productManager对象上调用List()函数?我可以看到类型的函数,甚至在index()处理程序中获取正确的类型名称。

英文:

Here's what I'm trying to do:

package products

ProductManager struct {
	products []*Product
    index    int64
}

func NewPM() *ProductManager {
	return &ProductManager{}
}

func (p *ProductManager) List() []*Product {
	return p.products
}

---

var productManager = products.NewPM()

func main() {
	api := Api{}
	api.Attach(productManager, "/products")
}

func (api Api) Attach(rm interface{}, route string) {
	// Apply typical REST actions to Mux.
	// ie: Product - to /products
	mux.Get(route, http.HandlerFunc(index(rm)))
}

func index(rm interface{}) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// allRecords := rm.List() - DOESN'T WORK. No method found.
		result := reflect.TypeOf(rm) // Works, shows me the correct type.
		method := result.Method(0).Name // Works as well! Shows me a function on the type.
		w.Write([]byte(fmt.Sprintf("%v", method)))
	}
}

Any idea on why I can't call the List() function on my productManager object? I can see the Type's functions and even get the right Type name in the index() handler.

答案1

得分: 2

简单来说,rm是一个空接口变量,因此它没有任何方法,这正是interface{}的含义:没有方法。如果你知道rm的动态类型是*ProductManager,你可以进行类型断言(但这样你可以传递一个*ProductManager)。也许在长期运行中,你需要对rm进行类型切换。顺便说一句:几乎总是使用interface{}都是一个不好的主意。

英文:

Dead simple: rm is an empty interface variable, so it does not have any methods, that's exactly what interface{} means: No methods. If you know that rm's dynamic type is *ProductManager you can type assert it (but than you could pass a *ProductManager) Maybe you'll have to type switch on rm in the longer run. (BTW: using interface{} is almost always a bad idea.)

huangapple
  • 本文由 发表于 2014年5月21日 21:50:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/23785225.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定