英文:
Can I instance differenct types according to string in golang?
问题
我想在Go语言中实现MVC模式。但是似乎很难实现我想要的效果。
在Testcontroller.go文件中,我有以下代码:
func (c *TestController) Test() {
//
}
func (c *TestController) Index() {
//
}
只有一个控制器时,我可以使用reflect.ValueOf(TestController{}).MethodByName().Call()
来执行该函数。
现在我想添加另一个控制器,但是似乎我无法通过不同的字符串创建不同的实例:
controllerName := strings.Split(r.URL.Path, "/")
controller = reflect.ValueOf(controllerName[1])
我知道这是完全错误的,但我希望如果controllerName
等于"Test",我可以得到一个TestController
实例,如果controllerName
等于"Index",我可以得到一个IndexController
实例。使用反射似乎无法实现我想要的效果。有没有其他方法可以做到这一点呢?
非常感谢!
英文:
I want to implement MVC in golang. But it seems like hard to achieve what I want.
in Testcontroller.go I have:
func (c *TestController) Test() {
//
}
func (c *TestController) Index() {
//
}
With only a controller, I can use reflect.ValueOf(TestController{}).MethodByName().Call() to execute that function.
now I want to add another controller. but It seems like I can't new different instance by different string:
controllerName := strings.Split(r.URL.Path, "/")
controller = reflect.ValueOf(controllerName[1])
I know this is totaly wrong, but I hope I can get a TestController instance if controllerName == "Test" and get a IndexController instance if controllerName == "Index", using reflect seems can't achieve what I want. Is there any way to do is?
Thank you very much!
答案1
得分: 2
你可以这样做:
为你的控制器定义一个接口:
type Controller interface {
// Route 返回该控制器的根路由
Route() string
}
在控制器中实现它:
// 这告诉我们的应用程序这个控制器的路由是什么
func (c *TestController) Route() string {
return "test"
}
func (c *TestController) Test() {
//
}
func (c *TestController) Index() {
//
}
在我们的应用程序中,创建一个控制器的注册表,你可以查找它们:
var controllers = make([]Controller, 0)
// 以某种方式进行注册
现在在服务过程中:
假设路径是 /<controller>/<method>
controllerName := strings.Split(r.URL.Path, "/")
// 再次,你可以在这里使用一个映射,但对于几个控制器来说可能不值得
for _, c := range controllers {
if c.Route() == controllerName[1] {
// 做你在单个控制器示例中所做的事情
callControllerWithReflection(c, controllerName[2])
}
}
希望对你有所帮助!
英文:
You could do something like that:
Define an interface for your controllers:
type Controller interface {
// Route returns the root route for that controller
Route() string
}
In a controller just implement it:
// this tells our app what's the route for this controller
func (c *TestController) Route() string {
return "test"
}
func (c *TestController) Test() {
//
}
func (c *TestController) Index() {
//
}
In our app, create a registry of your controllers, and you can look them up:
var controllers = make([]Controller, 0)
// register them somehow
And now in the serving process:
// assuming the path is /<controller>/<method>
controllerName := strings.Split(r.URL.Path, "/")
// again, you can use a map here, but for a few controllers it's not worth it probably
for _, c := range controllers {
if c.Route() == controllerName[1] {
// do what you did in the single controller example
callControllerWithReflection(c, controllerName[2])
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论