为什么控制器中的 Revel 可选功能参数不起作用? CRUD 代码冗余
Why are Revel optional func parameters in controller not working? CRUD code redundancy
我阅读了很多有关 Go 的文章,发现我不能在方法或函数中使用可选参数(某些参数也不能使用默认值)。
让我们以简单的 CRUD.
为例
我想使用相同的控制器操作来创建和更新,只是为了简单:
func (c Account) User(user models.User, verifyPassword string, id ...int64) {
/*
validate user etc
*/
if len(id) > 0 {
c.Txn.Update(&model)
} else{
c.Txn.Insert(&model)
}
}
当我尝试在模板中执行 {{ url "Account.User" }}
时,
我收到一条错误消息,说我缺少参数。
一旦我对路由的值进行硬编码,我就会在代码的未知部分出现一些无效的内存地址或零指针取消引用。
如果没有 optional/default 参数,我将拥有我不想要的 CRUD 代码冗余!
因此,我将不得不为同一件事使用两个函数,而不是一个函数,它们仅在一行代码中有所不同。
自从我 7 天前开始学习 Go 和 Revel 以来,也许我错过了什么。
我使用 Go 和 Revel 的唯一原因是速度。
我正在将它用于一些有很多请求(每天数百万)的项目。
有什么办法可以解决吗?
更新
第一个问题在视图上:{{ url "Account.User" }}
当我这样使用它时,它说:
missing parameter id for route Account.User in func (c Account) User(user models.User, verifyPassword string, id ...int64)
所以这比 Go 更像是 Revel 问题。
与其他问题一样,有很多方法可以解决这个问题。简单明显的解决方案(适用于任何语言)是将通用逻辑移至辅助方法中,并提供两个接受不同参数的包装器。话虽如此,我认为没有必要,也无法真正理解你的问题是什么,因为你的代码工作得很好......我下面的示例程序清楚地表明你可以用 0 个或更多参数调用该方法并决定要做什么根据存在的数量进行操作。
package main
import "fmt"
func main() {
Test()
Test(1)
Test(1, 2)
Test(1, 2, 3, 4)
}
func Test(numbers ... int) {
fmt.Println(len(numbers))
}
我猜你的意图是在提供了 id 时进行更新(如果有 id 则表明存在现有记录),如果没有则进行插入。我的另一个猜测是您对如何调用该方法感到困惑,而不是如何定义它。您的定义看起来很好,只要您正确调用它,它就应该按照您的预期工作。最后,我认为您可能滥用了 ...
语言功能。如果 id 的长度旨在为 1 或 0,并且您正在使用可变长度数组来替代真正的可选参数,那么您可能应该停止这样做。您可以只使用 2 个参数,一个 bool 表示 'update' 和一个表示 id 的 int。如果 update 为 false,则调用 update 并且不传递 id。
或者您可以尝试可变参数解析,例如 Python 如何使用 *args
func (c Account) User(args ...interface{}) {
for _, arg := range args {
switch v := arg.(type) {
case models.User:
// validate user
case string:
// verify password
case []int64:
if len(v) > 0 {
c.Txn.Update(&model)
} else {
c.Txn.Insert(&model)
}
default:
// some default stuff
}
}
}
我阅读了很多有关 Go 的文章,发现我不能在方法或函数中使用可选参数(某些参数也不能使用默认值)。 让我们以简单的 CRUD.
为例我想使用相同的控制器操作来创建和更新,只是为了简单:
func (c Account) User(user models.User, verifyPassword string, id ...int64) {
/*
validate user etc
*/
if len(id) > 0 {
c.Txn.Update(&model)
} else{
c.Txn.Insert(&model)
}
}
当我尝试在模板中执行 {{ url "Account.User" }}
时,
我收到一条错误消息,说我缺少参数。
一旦我对路由的值进行硬编码,我就会在代码的未知部分出现一些无效的内存地址或零指针取消引用。
如果没有 optional/default 参数,我将拥有我不想要的 CRUD 代码冗余!
因此,我将不得不为同一件事使用两个函数,而不是一个函数,它们仅在一行代码中有所不同。
自从我 7 天前开始学习 Go 和 Revel 以来,也许我错过了什么。 我使用 Go 和 Revel 的唯一原因是速度。 我正在将它用于一些有很多请求(每天数百万)的项目。
有什么办法可以解决吗?
更新
第一个问题在视图上:{{ url "Account.User" }}
当我这样使用它时,它说:
missing parameter id for route Account.User in func (c Account) User(user models.User, verifyPassword string, id ...int64)
所以这比 Go 更像是 Revel 问题。
与其他问题一样,有很多方法可以解决这个问题。简单明显的解决方案(适用于任何语言)是将通用逻辑移至辅助方法中,并提供两个接受不同参数的包装器。话虽如此,我认为没有必要,也无法真正理解你的问题是什么,因为你的代码工作得很好......我下面的示例程序清楚地表明你可以用 0 个或更多参数调用该方法并决定要做什么根据存在的数量进行操作。
package main
import "fmt"
func main() {
Test()
Test(1)
Test(1, 2)
Test(1, 2, 3, 4)
}
func Test(numbers ... int) {
fmt.Println(len(numbers))
}
我猜你的意图是在提供了 id 时进行更新(如果有 id 则表明存在现有记录),如果没有则进行插入。我的另一个猜测是您对如何调用该方法感到困惑,而不是如何定义它。您的定义看起来很好,只要您正确调用它,它就应该按照您的预期工作。最后,我认为您可能滥用了 ...
语言功能。如果 id 的长度旨在为 1 或 0,并且您正在使用可变长度数组来替代真正的可选参数,那么您可能应该停止这样做。您可以只使用 2 个参数,一个 bool 表示 'update' 和一个表示 id 的 int。如果 update 为 false,则调用 update 并且不传递 id。
或者您可以尝试可变参数解析,例如 Python 如何使用 *args
func (c Account) User(args ...interface{}) {
for _, arg := range args {
switch v := arg.(type) {
case models.User:
// validate user
case string:
// verify password
case []int64:
if len(v) > 0 {
c.Txn.Update(&model)
} else {
c.Txn.Insert(&model)
}
default:
// some default stuff
}
}
}