英文:
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
。
当你实现Show
、Create
等方法时,你使用了
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论