如何在Go中封装可变参数?

huangapple go评论69阅读模式
英文:

How do you wrap var args in Go?

问题

根据几个群组的帖子,以下代码应该可以工作:

package main

import "fmt"

func demo(format string, args ...interface{}) {
  var count = len(args)
  for i := 0; i < count; i++ {
    fmt.Printf("! %s\n", args[i])
  }
  fmt.Printf("%+v\n", format)
  fmt.Printf("%+v\n", args)
  fmt.Printf(format, args)
  fmt.Printf("\n")
}

func main() {
  demo("%s %d", "Hello World", 10)
  fmt.Printf("\n\n")
  demo("%d %s", 10, "Hello")
}

但是它并没有产生"Hello World 10"和"10 Hello",而是产生了:

! Hello World
! %!s(int=10)
%s %d
[Hello World 10]
[Hello World %!s(int=10)] %d(MISSING)


! %!s(int=10)
! Hello
%d %s
[10 Hello]
[10 %!d(string=Hello)] %s(MISSING)

也就是说,将[]interface{}传递给以...interface{}作为参数的函数时,不会展开参数,而只是将其作为值传递。第一个%s将[]interface{}展开为字符串,而后续的参数没有被处理。

我确定在日志记录中可能有很多需要这样做的情况,但我找不到任何可以工作的示例。

这基本上就是C语言中的'vprintf'函数族。

英文:

According to several groups posts, the following code should work:

package main

import &quot;fmt&quot;

func demo(format string, args ...interface{}) {
  var count = len(args)
  for i := 0; i &lt; count; i++ {
    fmt.Printf(&quot;! %s\n&quot;, args[i])
  }
  fmt.Printf(&quot;%+v\n&quot;, format)
  fmt.Printf(&quot;%+v\n&quot;, args)
  fmt.Printf(format, args)
  fmt.Printf(&quot;\n&quot;)
}

func main() {
  demo(&quot;%s %d&quot;, &quot;Hello World&quot;, 10)
  fmt.Printf(&quot;\n\n&quot;)
  demo(&quot;%d %s&quot;, 10, &quot;Hello&quot;)
}

And yield "Hello World 10" and "10 Hello", but it does not. Instead it yields:

! Hello World
! %!s(int=10)
%s %d
[Hello World 10]
[Hello World %!s(int=10)] %d(MISSING)


! %!s(int=10)
! Hello
%d %s
[10 Hello]
[10 %!d(string=Hello)] %s(MISSING)

Which is to say that passing []interface{} to a function that takes ...interface{} as an argument does not expand the argument and instead simply passes it as the value. The first %s expands the []interface{} into a string, and no further arguments are processed.

I'm sure there must be lots of situations where this is required in logging; but I can't find any working examples of how to do it.

This is basically the 'vprintf' family of functions in C.

答案1

得分: 10

我不认为 OP 程序应该“工作”。也许这是打算的替代方式(?):

package main

import "fmt"

func demo(format string, args ...interface{}) {
        fmt.Printf(format, args...)
}

func main() {
        demo("%s %d\n\n", "Hello World", 10)
        demo("%d %s", 10, "Hello")
}

(还有这里


输出:

Hello World 10

10 Hello
英文:

I don't think the OP program should "work". Maybe this was intended instead(?):

package main

import &quot;fmt&quot;

func demo(format string, args ...interface{}) {
        fmt.Printf(format, args...)
}

func main() {
        demo(&quot;%s %d\n\n&quot;, &quot;Hello World&quot;, 10)
        demo(&quot;%d %s&quot;, 10, &quot;Hello&quot;)
}

(Also here


Output:

Hello World 10

10 Hello

答案2

得分: 4

fmt.Printf(format, args...)应该可以实现你想要的功能。

英文:

fmt.Printf(format, args...) should do what you want I think.

huangapple
  • 本文由 发表于 2013年2月6日 21:25:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/14730201.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定