通过字符串创建一个结构体的实例。

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

make a instance of a struct by string

问题

我正在构建一个应用程序,想在其中使用一个简单的MVC模型。

我有一个包含控制器结构的控制器包,如下所示:

type UserController struct {}

func (u *UserController) Index(res http.ResponseWriter, req http.Request) {
  // 在这里写一些代码
}

我想实现的目标是,通过字符串来创建该控制器的实例,例如:

func NewAppController("user") { }

这样我就可以根据我的路由请求动态地创建控制器的实例。

我还考虑了另一种方式,就是像这样映射我的控制器:

var controllerProvider = map[string]interface{} {
   "user": &controllers.UserController{},
   "warehouse": &controllers.WarehouseController{},
}

然后通过以下方式调用:

appController = mux.Vars(req)["controller"]
c := controllerProvider[appController]

但我更倾向于使用第一种方式,你有什么办法来处理这个问题吗?

英文:

i am building a app and i want to use a simple mvc model in it

i have a package controllers with in there controller structs like this

type UserController struct {}

func (u *UserController) Index(res http.ResponseWriter, req http.Request) {
  // some code in it
}

what i want to achieve is that i can make instance of that controller by string like

func NewAppController("user") { }

so i can dynamicly create instances of my controllers by my route requests

an other way i think about is to map my controllers like this

var controllerProvider = map[string]interface{} {
   "user": &controllers.UserController{},
   "warehouse": &controllers.WarehouseController{},
 }

and then call it by

appController = mux.Vars(req)["controller"]
c := controllerProvider[appController]

but i rather use the first way any idea how to deal with this?

答案1

得分: 2

你可以尝试创建一个实现了reflect.Type接口的新对象,然后通过reflect的机制来使用它,但这似乎是完全浪费时间。相反,考虑以下几种替代方案:

  • 创建一个包含字段Name stringMethods map[string]ActionFunc的结构体。这种方法可以工作,但在我看来并不是很符合惯用方式。(如果说有什么的话,这让我想起了一些JavaScript的面向对象编程实现。)

  • 使用一个框架。如果你熟悉MVC,为什么不使用已经存在的Go MVC框架之一呢?Beego和Revel是我想到的几个。

  • 重新思考你的架构。从我现在看到的情况来看,你试图像写Ruby-on-Rails一样写Go。但Go是不同的。从基本的net/http开始,创建一个最小实现的应用程序原型。有了这个原型,你可以重写和扩展它。需要资源路由?添加gorilla/mux或其他选择的路由器。需要数据存储?添加一个ORM。想要更多的可测试性和灵活性?到处都是接口。

英文:

You could try to create a new object that implements reflect.Type interface and then use it through reflect's mechanisms, but it looks like a complete waste of time. Instead, consider these alternatives:

  • Make a struct with fields like Name string and Methods map[string]ActionFunc. This would work, but it doesn't look very idiomatic to me. (If anything, this reminds of some JavaScript OOP implementations.)

  • Use a framework. If you're comfortable with MVC, why don't you use one of MVC frameworks for Go that already exist? Beego and Revel come to mind.

  • Rethink your architecture altogether. From what I see now, you are trying to write Go like it's Ruby-on-Rails. Go is different. Start with vanilla net/http and create a minimal implementation of your app. That's your prototype. With that prototype on your hands, you can rewrite it and expand it. Want resourceful routes? Add gorilla/mux or another router of choice. Need a data storage? Add an ORM. Want more testability and flexibility? Interfaces, interfaces everywhere.

答案2

得分: 0

如果你使用以下代码:

var controllerProvider = map[string]interface{}{
   "user": &controllers.UserController{},
   "warehouse": &controllers.WarehouseController{},
}

请注意,这些不是每次访问都会创建新实例。如果你多次使用controllerProvider,它将始终返回指向只初始化一次的实例的指针。

你可能希望使用函数来动态生成实例:

var controllerProvider = map[string]func() interface{}{
	"user":      func() interface{} { return &controllers.UserController{} },
	"warehouse": func() interface{} { return &controllers.WarehouseController{} },
}

c := controllerProvider[appController]()
英文:

If you use this:

var controllerProvider = map[string]interface{} {
   "user": &controllers.UserController{},
   "warehouse": &controllers.WarehouseController{},
 }

Be careful, these are not new instances for each access. If you use controllerProvider several times, it will always return the pointer to the instances initialized only once there.

You might want to use functions to dynamically generate instances:

var controllerProvider = map[string]func() interface{}{
	"user":      func() interface{} { return &controllers.UserController{} },
	"warehouse": func() interface{} { return &controllers.WarehouseController{} },
}

c := controllerProvider[appController]()

huangapple
  • 本文由 发表于 2014年7月16日 16:17:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/24775603.html
匿名

发表评论

匿名网友

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

确定