Go语言可以像Python一样对字符串进行乘法运算吗?

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

Can Golang multiply strings like Python can?

问题

Python可以像这样对字符串进行乘法运算:

Python 3.4.3 (默认, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
输入 "help", "copyright", "credits" 或 "license" 获取更多信息。
>>> x = 'my new text is this long'
>>> y = '#' * len(x)
>>> y
'########################'
>>>

Golang能以某种方式实现相同的功能吗?

英文:

Python can multiply strings like so:

Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 'my new text is this long'
>>> y = '#' * len(x)
>>> y
'########################'
>>>

Can Golang do the equivalent somehow?

答案1

得分: 153

它使用了一个函数而不是一个运算符,strings.Repeat。这是你的Python示例的一个转换版本,你可以在这里运行:

package main

import (
	"fmt"
	"strings"
	"unicode/utf8"
)

func main() {
	x := "my new text is this long"
	y := strings.Repeat("#", utf8.RuneCountInString(x))
	fmt.Println(x)
	fmt.Println(y)
}

请注意,我使用了utf8.RuneCountInString(x)代替了len(x);前者计算"runes"(Unicode代码点)的数量,而后者计算字节数。在"my new text is this long"的情况下,这两者的区别并不重要,因为所有的runes都只占用一个字节,但是养成明确指定你的意图的习惯是很好的:

len("ā") //=> 2
utf8.RuneCountInString("ā") //=> 1

由于这是一个Python比较的问题,请注意在Python中,函数len根据你调用它的对象而计算不同的内容。在Python 2中,它对普通字符串计算字节数,对Unicode字符串(u'...')计算runes:

Python 2.7.18 (default, Aug 15 2020, 17:03:20)
>>> len('ā') #=> 2
>>> len(u'ā') #=> 1

而在现代的Python中,普通字符串就是Unicode字符串:

Python 3.9.6 (default, Jun 29 2021, 19:36:19) 
>>> len('ā') #=> 1

如果你想计算字节数,你需要先将字符串编码为bytearray

>>> len('ā'.encode('UTF-8')) #=> 2

因此,Python有多种类型的字符串和一个函数来获取它们的长度;而Go只有一种字符串类型,但你需要选择与你想要的语义相匹配的长度函数。

另外值得注意的是,Golang中的"rune"的概念不能解决Unicode中的一个问题,即"一个字符有多长?"这个问题并没有一个明确定义的答案。之前我使用字符串"ā"作为一个由两个字节组成的一个rune字符串的例子。但是这个看起来非常相似的字符串 - "ā" - 实际上是由四个字节或两个runes组成的。第一个是U+0101 LATIN SMALL LETTER A WITH MACRON,而第二个是U+0061 LATIN SMALL LETTER A后跟U+0304 COMBINING MACRON。正确的Unicode处理将把它们视为相等(根据选择的规范形式选择其中一个作为规范形式),但从根本上讲,它们都等同于一个包含确定数量的代码点的理想字符串是没有意义的。

英文:

It has a function instead of an operator, strings.Repeat. Here's a port of your Python example, which you can run here:

package main

import (
	"fmt"
	"strings"
	"unicode/utf8"
)

func main() {
	x := "my new text is this long"
	y := strings.Repeat("#", utf8.RuneCountInString(x))
    fmt.Println(x)
	fmt.Println(y)
}

Note that I've used utf8.RuneCountInString(x) instead of len(x); the former counts "runes" (Unicode code points), while the latter counts bytes. In the case of "my new text is this long", the difference doesn't matter since all the runes are only one byte each, but it's good to get into the habit of specifying what you mean:

len("ā") //=> 2
utf8.RuneCountInString("ā") //=> 1

Since this was a Python comparison question, note that in Python, the one function len counts different things depending on what you call it on. In Python 2, it counted bytes on plain strings and runes on Unicode strings (u'...'):

Python 2.7.18 (default, Aug 15 2020, 17:03:20)
>>> len('ā') #=> 2
>>> len(u'ā') #=> 1

Whereas in modern Python, plain strings are Unicode strings:

Python 3.9.6 (default, Jun 29 2021, 19:36:19) 
>>> len('ā') #=> 1

If you want to count bytes, you need to encode the string into a bytearray first:

>>> len('ā'.encode('UTF-8')) #=> 2

So Python has multiple types of string and one function to get their lengths; Go has only one kind of string, but you have to pick the length function that matches the semantics you want.

Oh, it's also worth noting that the Golang concept of a "rune" doesn't (and can't) solve the problem that in Unicode, the question "How much string is one character?" does not always have a well-defined answer. Earlier I used the string "ā" as an example of a two-byte one-rune string. But this very similar-looking string - "ā" – is actually four bytes or two runes long. The first one is U+0101 LATIN SMALL LETTER A WITH MACRON, while the second is U+0061 LATIN SMALL LETTER A followed by U+0304 COMBINING MACRON. Proper Unicode processing will treat them as equal to each other (picking one of them as the normalized form depending on which Normalization Form is selected) but there's not really any sense in which the Platonic ideal string they're both equivalent to can be said to contain a definite number of code-points.

答案2

得分: 28

是的,它可以,尽管不是通过运算符,而是通过标准库中的一个函数实现。

使用简单的循环非常容易,但是标准库提供了一个高度优化的版本:strings.Repeat()

你的示例代码:

x := "my new text is this long"
y := strings.Repeat("#", len(x))
fmt.Println(y)

Go Playground上尝试一下。

注意:len(x) 是字符串的字节长度(以UTF-8编码表示,在Go中存储字符串的方式),如果你想要字符的数量(符文),可以使用utf8.RuneCountInString()

英文:

Yes, it can, although not with an operator but with a function in the standard library.

It would be very easy with a simple loop, but the standard library provides you a highly optimized version of it: strings.Repeat().

Your example:

x := "my new text is this long"
y := strings.Repeat("#", len(x))
fmt.Println(y)

Try it on the Go Playground.

Notes: len(x) is the "bytes" length (number of bytes) of the string (in UTF-8 encoding, this is how Go stores strings in memory). If you want the number of characters (runes), use utf8.RuneCountInString().

答案3

得分: 3

是的。strings包中有一个Repeat函数

英文:

Yup. The strings package has a Repeat function.

答案4

得分: 0

你可以使用字符串包(string package)。它有一个重复函数这里

英文:

you can use the string package. it has a repeat functionhere

huangapple
  • 本文由 发表于 2015年10月15日 10:52:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/33139020.html
匿名

发表评论

匿名网友

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

确定