为什么控制器中的Revel可选功能参数不起作用? CRUD代码冗余

时间:2015-06-08 23:26:50

标签: go revel

我正在阅读关于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" }}时, 我得到一个错误,说我缺少参数。 一旦我硬编码路由值,我就会在代码的未知部分找到一些无效的内存地址或nil指针解除引用。

如果没有可选/默认参数,我将为CRUD提供我不想要的代码冗余!

因此,我必须使用两个函数来代替一个函数,而只需要在一行代码中使用两个函数。

自从七天前我开始学习Go and 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。

2 个答案:

答案 0 :(得分:0)

与其他任何方法一样,有很多方法可以解决这个问题。简单明显的解决方案(适用于任何语言)是将公共逻辑移动到辅助方法中,并在其周围提供两个接受不同参数的包装器。话虽如此,我认为没有必要,并且实际上无法理解您的问题是什么,因为您的代码工作得很好......下面的示例程序清楚地显示您可以调用方法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说'更新'和id的int。如果更新为false,则调用update并且不传递id。

答案 1 :(得分:0)

或者您可以尝试使用可变参数解析,就像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
        }
    }
}