为什么我的Go代码无法运行?

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

Why does my Go code not run?

问题

package main

import (
"fmt"
"github.com/ant0ine/go-json-rest"
"net/http"
)

type App struct {
Id string
Name string
}

func GetApp(w *rest.ResponseWriter, req *rest.Request) {
user := App{
Id: req.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&user)
}

type MyResourceHandler struct {
rest.ResourceHandler
}

type ResourceController interface {
Show(w *rest.ResponseWriter, req *rest.Request)
Create(w *rest.ResponseWriter, req *rest.Request)
Update(w *rest.ResponseWriter, req *rest.Request)
Delete(w *rest.ResponseWriter, req *rest.Request)
}

func (self *MyResourceHandler) AddResource(name string, c ResourceController) error {
show_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Show(w, r)
}
create_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Create(w, r)
}
update_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Update(w, r)
}
delete_func := func(w *rest.ResponseWriter, r *rest.Request) {
c.Delete(w, r)
}

err := self.ResourceHandler.SetRoutes(
    rest.Route{"GET", fmt.Sprintf("/%s/:id", name), show_func},
    rest.Route{"POST", fmt.Sprintf("/%s", name), create_func},
    rest.Route{"PUT", fmt.Sprintf("/%s/:id", name), update_func},
    rest.Route{"DELETE", fmt.Sprintf("/%s/:id", name), delete_func},
)
return err

}

type AppController struct{}

func (self *AppController) Show(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}

func (self *AppController) Create(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}

func (self *AppController) Update(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}

func (self *AppController) Delete(w *rest.ResponseWriter, r *rest.Request) {
app := App{
Id: r.PathParam("id"),
Name: "Antoine",
}
w.WriteJson(&app)
}

func main() {
handler := MyResourceHandler{}
controler := AppController{}
handler.AddResource("app", &controler)
http.ListenAndServe(":9008", &handler)
}

英文:
package main

import (
	"fmt"
	"github.com/ant0ine/go-json-rest"
	"net/http"
)

type App struct {
	Id   string
	Name string
}

func GetApp(w *rest.ResponseWriter, req *rest.Request) {
	user := App{
		Id:   req.PathParam("id"),
		Name: "Antoine",
	}
	w.WriteJson(&user)
}

type MyResourceHandler struct {
	rest.ResourceHandler
}

type ResourceController interface {
	Show(w *rest.ResponseWriter, req *rest.Request)
	Create(w *rest.ResponseWriter, req *rest.Request)
	Update(w *rest.ResponseWriter, req *rest.Request)
	Delete(w *rest.ResponseWriter, req *rest.Request)
}

func (self *MyResourceHandler) AddResource(name string, c ResourceController) error {
	show_func := func(w *rest.ResponseWriter, r *rest.Request) {
		c.Show(w, r)
	}
	create_func := func(w *rest.ResponseWriter, r *rest.Request) {
		c.Create(w, r)
	}
	update_func := func(w *rest.ResponseWriter, r *rest.Request) {
		c.Update(w, r)
	}
	delete_func := func(w *rest.ResponseWriter, r *rest.Request) {
		c.Delete(w, r)
	}

	err := self.ResourceHandler.SetRoutes(
		rest.Route{"GET", fmt.Sprintf("/%s/:id", name), show_func},
		rest.Route{"POST", fmt.Sprintf("/%s", name), create_func},
		rest.Route{"PUT", fmt.Sprintf("/%s/:id", name), update_func},
		rest.Route{"DELETE", fmt.Sprintf("/%s/:id", name), delete_func},
	)
	return err
}

type AppController struct{}

func (self *AppController) Show(w *rest.ResponseWriter, r *rest.Request) {
	app := App{
		Id:   r.PathParam("id"),
		Name: "Antoine",
	}
	w.WriteJson(&app)
}

func (self *AppController) Create(w *rest.ResponseWriter, r *rest.Request) {
	app := App{
		Id:   r.PathParam("id"),
		Name: "Antoine",
	}
	w.WriteJson(&app)
}

func (self *AppController) Update(w *rest.ResponseWriter, r *rest.Request) {
	app := App{
		Id:   r.PathParam("id"),
		Name: "Antoine",
	}
	w.WriteJson(&app)
}

func (self *AppController) Delete(w *rest.ResponseWriter, r *rest.Request) {
	app := App{
		Id:   r.PathParam("id"),
		Name: "Antoine",
	}
	w.WriteJson(&app)
}

func main() {
	handler := MyResourceHandler{}
	controler := AppController{}
	handler.AddResource("app", controler)
	http.ListenAndServe(":9008", &handler)
}

I have implemented all of four methods of interface ResourceController, but it tells me:

./fakeapi.go:93: cannot use controler (type AppController) as type ResourceController in function argument:
	AppController does not implement ResourceController (Create method requires pointer receiver)

答案1

得分: 4

这是错误信息中的内容:(Create方法需要指针接收器)

你在*AppController(指向AppController的指针)上定义了Create方法,但你正在尝试使用一个AppController,它不满足接口的要求。

你可能想要的解决方案是将controler := AppController{}更改为controler := &AppController{}

英文:

It's in the error message: (Create method requires pointer receiver)

You've defined Create on *AppController (pointer to an AppController), but you're trying to use an AppController, which does not satisfy the interface.

The solution you probably want is to change controler := AppController{} to controler := &AppController{}

答案2

得分: 2

如cthomo06所说,答案在错误中。

错误信息的原因是当你传递一个指针而不是一个值时,你只实现了ResourceController

当你实现ShowCreate等方法时,你使用了

func (self *AppController)...

这要求该方法获得一个指针接收器,但是AddResources给出的是controler,而不是指针。

下面是一些示例代码来展示这个问题:

package main

import "fmt"

type I interface {
    Show(i int)
}

type T struct{}

func (t *T) Show(i int) {
    fmt.Println(i)
}

func CallShow(i I) {
    i.Show(32);
}

func main() {
    obj := T{}
    
    // CallShow(obj) // 这个不起作用,除非你将func (t *T)改为func (t T)
    CallShow(&obj) // 这个起作用是因为你传递了一个指针
}
英文:

As cthom06 says, the answer is in the error.

The reason for the error message is that you have only implemented ResourceController when you are passing a pointer and not a value.

When you implemented Show, Create, etc., you used

func (self *AppController)...

This requires the method to get a pointer receiver, but AddResources is given the value of controler, not the pointer.

Here is some example code to show the problem:

package main

import "fmt"

type I interface {
	Show(i int)
}

type T struct{}

func (t *T) Show(i int) {
	fmt.Println(i)
}

func CallShow(i I) {
	i.Show(32);
}

func main() {
	obj := T{}
	
	// CallShow(obj) // This doesn't work unless you change func (t *T) to func (t T)
	CallShow(&obj) // This works because you pass a pointer
}

答案3

得分: 0

同时,“ResourceHandler”已被弃用。我建议使用v3 API:

api := rest.NewApi()
api.Use(rest.DefaultDevStack...)
router, err := rest.MakeRouter(
   // 在这里添加你的路由...
)
if err != nil {
    log.Fatal(err)
}
api.SetApp(router)
log.Fatal(http.ListenAndServe(":8080", api.MakeHandler()))

Antoine - go-json-rest 作者

英文:

Also "ResourceHandler" is deprecated. I would recommend to use the v3 API:

api := rest.NewApi()
api.Use(rest.DefaultDevStack...)
router, err := rest.MakeRouter(
   // your routes here ...
)
if err != nil {
    log.Fatal(err)
}
api.SetApp(router)
log.Fatal(http.ListenAndServe(":8080", api.MakeHandler()))

Antoine - go-json-rest author

huangapple
  • 本文由 发表于 2013年3月28日 19:15:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/15680370.html
匿名

发表评论

匿名网友

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

确定