卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34870本站已运行393

可变参数函数中是否需要格式化指令?

可变参数函数中是否需要格式化指令?

在PHP中,可变参数函数是一种非常方便的功能,允许我们在函数定义中使用不定数量的参数。然而,是否需要在可变参数函数中使用格式化指令则取决于具体的需求。格式化指令通常用于将参数以特定的格式输出或处理,比如使用printf()函数时需要指定格式化字符串。如果在可变参数函数中需要对参数进行格式化操作,那么当然是需要使用格式化指令的。但如果只是简单地将参数传递给其他函数或进行一些基本的操作,那么就不需要使用格式化指令了。总之,是否需要在可变参数函数中使用格式化指令,取决于具体的业务需求。

问题内容

我有一个可变参数函数 respond ,它接受几个位置参数,并在末尾传播一个 any 切片。根据上下文,该函数以不同的方式使用最后一个参数(请注意 messagedata 如何根据 status 的值而有所不同。):

func respond(w http.responsewriter, status int, format string, a ...any) {
    var (
        statusok bool
        message  string
        data     interface{}
    )
    if status >= 300 {
        statusok = false
        message = fmt.sprintf(format, a...)
        data = nil
        log.error().msg(message)
    } else {
        statusok = true
        message = format
        data = a[0]
        log.info().msg(fmt.sprintf("%d", status))
    }
    // issue response
    responder := render.new()
    responder.json(w, status, map[string]interface{}{
        "statusok": statusok,
        "status":   status,
        "message":  message,
        "data":     data,
    })
}

对于下面的调用,我没有收到任何警告:

respond(w, http.statusnotfound, "person %v does not exist", personid)

但是,对于下一个,警告 respond 调用有参数,但没有引发格式化指令 (但代码按预期运行,personstruct):

respond(w, http.StatusAccepted, "updated", person)

以我的业余眼光来看,看起来可变参数函数希望在末尾有一个格式化字符串和该格式的参数。但为什么会这样呢?可变参数函数的作用是否有限制?

或者我应该更好地将 responder 分成两部分,每种情况一个(“ok”和“not ok”)?

另请参阅 https://github.com/golang/go/issues/26486 和 https://go.dev/src/cmd/vet/testdata/print/print.go (第 316 行)进行讨论go 代码中的该消息(我收到的是来自 linter 的警告,正如 @mkopriva 和 @jimb 在他们的评论中提到的那样)

解决方法

警告来自 linter,因为您调用 respond() 函数时使用的格式字符串与之后提供的参数不匹配。

此特定消息来自 printf 分析器< /a> 其中记录了:

printf:检查 printf 格式字符串和参数的一致性

该检查适用于对格式化函数(例如 fmt.printf 和 fmt.sprintf)的调用,以及任何检测到的这些函数的包装器

由于您的 response() 函数使用 formata 参数按原样调用 fmt.sprintf(),因此这被视为 fmt.sprintf() 的包装器。

如果您想避免/摆脱此警告消息,最简单的“修复”是不按原样使用这些参数,例如复制其中一个参数,然后将其传递:

// Make and use a copy to avoid being marked as a wrapper of fmt.Sprintf
format := format
message = fmt.Sprintf(format, a...)
卓越飞翔博客
上一篇: 为什么我只收到部分错误,而不是我启动的 goroutine 中的所有错误?
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏