0

我正在阅读很多关于 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 代码冗余!

因此,我将不得不为同一件事使用两个函数,而不是一个函数,这两个函数仅在一行代码中有所不同。

自从我 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)

所以这更像是一个 Revel 问题,然后是 Go。

4

2 回答 2

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 个参数,一个表示“更新”的布尔值和一个表示 id 的 int。如果 update 为 false,则调用 update 并且不传递 id。

于 2015-06-09T00:06:02.033 回答
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
        }
    }
}
于 2015-06-09T04:37:07.750 回答