为什么要使用 fmt.Sprint?

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

Why would you use fmt.Sprint?

问题

我真的不理解使用fmt.Sprint与使用+将字符串连接起来的好处。以下是两者的使用示例:

func main() {
    myString := fmt.Sprint("Hello", "world")
    fmt.Println(myString)
}

func main() {
    myString := "Hello " + "World"
    fmt.Println(myString)
}

它们之间有什么区别和好处呢?

英文:

I really don't understand the benefit of using fmt.Sprint compared to add strings together with +. Here is an example of both in use:

func main() {
    myString := fmt.Sprint("Hello", "world")
    fmt.Println(myString)
}

and

func main() {
    myString := "Hello " + "World"
    fmt.Println(myString)
}

What is the differences and benefits of each?

答案1

得分: 37

在你的示例中,由于你使用Sprintf来简单地连接字符串,所以没有真正的区别。实际上,使用"+"运算符可以更容易地解决这个问题。

以以下示例为例,你想要打印一个清晰的错误消息,例如"找不到ID为'42'的产品。"。使用你的底层方法会是什么样子?

productID := 42;
myString := "Product with ID '" + productID + "' could not be found.";

这会导致错误(类型不匹配:string和int),因为Go语言不支持将不同类型连接在一起。

所以你需要先将类型转换为字符串。

productID := 42
myString := "Product with ID '" + strconv.Itoa(productID) + "' could not be found.";

而且,对于除了字符串以外的每种数据类型,你都需要进行这样的转换。

Go语言中的fmt包以及其他几乎所有语言中类似的格式化包通过帮助你进行转换并保持字符串清晰,避免了大量的"+"运算符。

下面是使用fmt的示例:

product := 42
myString := fmt.Sprintf("Product with ID '%d' could not be found.", product)

这里的%d是格式化动词,用于将参数打印为数字。请参阅https://golang.org/pkg/fmt/#hdr-Printing 了解其他打印其他类型的方式。

与连接字符串相比,fmt允许你以清晰的方式编写字符串,将模板/文本与变量分开。而且,它大大简化了打印除字符串以外的数据类型的操作。

英文:

In your example there are no real differences as you are Sprintf to simply concaternate strings. That is indeed something which can be solved more easily by using the '+' operator.

Take the following example, where you want to print a clear error message like "Product with ID '42' could not be found.". How does that look with your bottom approach?

productID := 42;
myString := "Product with ID '" + productID + "' could not be found."

This would give an error (mismatched types string and int), because Go does not have support for concatenate different types together.

So you would have to transform the type to a string first.

productID := 42
myString := "Product with ID '" + strconv.Itoa(productID) + "' could not be found."

And, this you would have to do for every single data type other than strings.

The fmt package in Go and similar formatting packages in almost any other language solve this by helping you with the conversions and keeping your strings clear of mass '+' operators.

Here is how the example would look like using fmt

product := 42
myString := fmt.Sprintf("Product with ID '%d' could not be found.", product)

Here %d is the formatting verb for 'print the argument as a number'. See https://golang.org/pkg/fmt/#hdr-Printing the various other ways of printing other types.

Compared to concatenating fmt allows you to write your strings in a clear way, separating the template/text from the variables. And, it simplifies printing data types other than strings a lot.

答案2

得分: 6

fmt.Sprint 适用于连接不同类型的参数,因为它在内部使用了反射。所以,如果你需要连接字符串,可以使用 "+",它速度更快。但是,如果你需要连接数字和字符串,可以像这样使用 fmt.Sprint

message := fmt.Sprint(500, "内部服务器错误")
英文:

fmt.Sprint is good for concatenation different types of its parameters as it uses reflection under the hood. So, if you need to concat strings - use "+", it's much faster, but if you need to contact number and your profit fmt.Sprint just like that:

message := fmt.Sprint(500, "internal server error")

答案3

得分: 2

如果你用连接的字符串作为参数调用一个函数,你将不得不在调用之前评估参数。然后,如果函数选择不对参数进行操作(比如在日志级别低于打印所需级别时进行日志记录),你已经承担了连接的开销。

非常类似于你的例子,在一种情况下你进行了连接,在另一种情况下没有。如果这些操作的数量很大,可能会变得明显。再次强调,日志记录是一个很好的例子。

Sprint的特定情况下,这当然不是那么重要,但也许保持一致性是个好主意?

英文:

If you call a function with concatenated string as argument, you will have to evaluate argument prior to call. Then if function chooses not to act on argument (think logging when log level is lower then needed for printing), you already incurred the overhead of concatenation.

Very similar to your example, in one case you do concatenation and in other not.
With high volume of those operations it may become noticeable. Again, logging is a good example.

In specific case of Sprint, it is not that relevant of course, but perhaps it's good to be consistent?

答案4

得分: 1

大部分的参数已经写好了,只有一个例外。使用Sprintf进行本地化更加容易,并且在程序员和本地化人员(会说外语的人)之间有更明确的角色定义。当然,并不是每个应用都真正需要这个功能。让我们选择:

s := fmt.Sprintf(t('"%s 是 %d 岁,来自 %s"'), name, age, place)

或者

s := name + t(' 是 ') + strconv.Itoa(age) + t(' 岁,来自 ') + place

翻译文本片段会让人感到困惑。而且,Sprintf 还允许你格式化数字等内容。

英文:

Most of the arguments have already been written, exclude one. Localization with Sprintf is much easier and has better defined roles between programmer and localizator (someone who speaks foreign language). Of course not each app really needs that. Let's choose:

s := fmt.Sprintf(t('%s is %d and comes from %s'), name, age, place)

or

s := name + t(' is ') + strconv.Itoa(age) + t(' and comes from ') + place

Translation of fragments of text is confusing. Also sprintf allows you formatting number etc

答案5

得分: 0

像@Erwin(被接受的答案)所说,“mismatched types”是一个与连接和使用“strconv”过于复杂的问题。

var unixTime = time.Now().Unix()
fmt.Println("这样不起作用:" + string(unixTime))

fmt.Println("Unix时间戳,基数10:" + strconv.FormatInt(unixTime, 10))
fmt.Println("Unix时间戳,Itoa:" + strconv.Itoa(int(unixTime)))

// 在我看来,这样看起来更清晰...
fmt.Println("Unix时间戳,Sprint:" + fmt.Sprint(unixTime))

由于Web开发通常涉及连接长字符串不会输出到stdout,我认为Sprint是一个有用的工具。

英文:

Like @Erwin (accepted answer) said, "mismatched types" is a problem with concatenation and using "strconv" seems overly complicated.

var unixTime = time.Now().Unix()
fmt.Println("This doesn't work: "+ string(unixTime))

fmt.Println("Unix timestamp, base 10: "+ strconv.FormatInt(unixTime, 10))
fmt.Println("Unix timestamp, Itoa: "+ strconv.Itoa(int(unixTime)))

// This looks cleaner, in my opinion... 
fmt.Println("Unix timestamp, Sprint: "+ fmt.Sprint(unixTime))

Since web development usually involves concatenation of long strings that aren't going to stdout, I see Sprint as a useful tool.

huangapple
  • 本文由 发表于 2017年7月20日 08:11:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/45203052.html
匿名

发表评论

匿名网友

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

确定