ChatGPT解决这个技术问题 Extra ChatGPT

你如何在 Go 中编写多行字符串?

Go 是否有类似于 Python 的多行字符串的东西:

"""line 1
line 2
line 3"""

如果不是,那么编写跨越多行的字符串的首选方法是什么?


A
Amin Shojaei

根据 language specification,您可以使用原始字符串文字,其中字符串由反引号而不是双引号分隔。

`line 1
line 2
line 3`

附带说明:所谓的“原始报价”不解析转义序列。因此,选择字符串文字来编写正则表达式模式,因为它们通常包含非标准转义序列,这会使 Go 编译器抱怨没有双重转义。它使模式保持干净且相对可读。
不过,在使用尾行空格时需要小心这一点。例如,如果您在 line 1 之后放置一个空格,它将在您的编辑器中不可见,但会出现在字符串中。
@DanieleD 这有点不合情理,但是哪种方言?大概主要是MySQL? stackoverflow.com/a/10574031 请注意,通过扩展相同的参数,嵌入 markdown 或 shell 脚本(如果您选择使用反引号代替 $(abcd))很麻烦。
@KyleHeuton:大概 Daniele D 在他/她的 SQL 查询中使用了反引号字符(正如 MySQL 用户经常做的那样),并且发现必须将其表示为 ` + "`" + ` 并破坏复制和粘贴是很痛苦的。
如果人们对 MySQL 有疑问,请注意您始终可以设置会话 sql 模式,例如 SET SESSION sql_mode = 'ANSI_QUOTES'; 这将是 Treat " as an identifier quote character (like the backtick quote character) and not as a string quote character. 然后确保对我见过的每个 SQL 数据库的字符串文字使用撇号 '做。见dev.mysql.com/doc/refman/5.7/en/…
S
Sebastian Lenartowicz

你可以写:

"line 1" +
"line 2" +
"line 3"

这与以下内容相同:

"line 1line 2line 3"

与使用反引号不同,它将保留转义字符。请注意,“+”必须位于“前导”行 - 例如,以下将产生错误:

"line 1"
+"line 2"

此解决方案与 Python 的多行字符串不同。它将字符串文字拆分为多行,但字符串本身不包含多行。
由于这保留了转义字符,因此可以简单地使用 \n 添加新行,并且更容易使用动态字符串等。如果我是正确的,那么接受的答案确实是代码中的静态字符串使其看起来很漂亮。
那不是也很低效吗?让字符串是 3x 一个 6 字符序列: 6 + 2*6 +3*6 = 36 个字符,最佳时分配为 18(由于字符串是不可变的,每次添加两个字符串时都会创建一个长度为两个字符串的新字符串字符串连接)。
@N0thing:如果只有字符串文字,则编译器将优化时没有运行时差异。但是编译时间有很小的差异(微秒,甚至纳秒)。
我相信这是获得带有 CRLF 行尾的多行字符串文字的最佳方法
k
kkm

对多行字符串使用原始字符串文字:

func main(){
    multiline := `line 
by line
and line
after line`
}

原始字符串文字

原始字符串文字是反引号之间的字符序列,如 `foo`。在引号内,可以出现除反引号外的任何字符。

一个重要的部分是原始文字不仅仅是多行而且多行并不是它的唯一目的。

原始字符串文字的值是由引号之间的未解释(隐式 UTF-8 编码)字符组成的字符串;特别是,反斜杠没有特殊含义......

因此不会解释转义,并且刻度之间的新行将是真正的新行。

func main(){
    multiline := `line 
by line \n
and line \n
after line`

    // \n will be just printed. 
    // But new lines are there too.
    fmt.Print(multiline)
}

级联

可能你有很长的线路想要打破,你不需要新的线路。在这种情况下,您可以使用字符串连接。

func main(){
    multiline := "line " +
            "by line " +
            "and line " +
            "after line"

    fmt.Print(multiline) // No new lines here
}

由于 " " 被解释字符串文字转义将被解释。

func main(){
    multiline := "line " +
            "by line \n" +
            "and line \n" +
            "after line"

    fmt.Print(multiline) // New lines as interpreted \n
}

C
Community

String literals

原始字符串文字支持多行(但不解释转义字符)

解释字符串字面量解释转义字符,如 '\n'。

但是,如果您的多行字符串必须包含反引号 (`),那么您将不得不使用解释的字符串文字:

`line one
  line two ` +
"`" + `line three
line four`

您不能直接将反引号 (`) 放在原始字符串文字 (``xx\) 中。
您必须使用(如“how to put a backquote in a backquoted string?”中所述):

 + "`" + ...

r
rynop

Go 和多行字符串

使用反引号你可以有多行字符串:

package main

import "fmt"

func main() {

    message := `This is a 
Multi-line Text String
Because it uses the raw-string back ticks 
instead of quotes.
`

    fmt.Printf("%s", message)
}

不要使用双引号 (") 或单引号 ('),而是使用反引号来定义字符串的开始和结束。然后,您可以将它换行。

但是,如果您缩进字符串,请记住空格会计算在内。

请检查 playground 并用它做实验。


B
Bilal Khan

在 Go 中创建多行字符串实际上非常容易。在声明或分配字符串值时,只需使用反引号 (`) 字符。

package main

import (
    "fmt"
)

func main() {
    // String in multiple lines
    str := `This is a
multiline
string.`
    fmt.Println(str + "\n")
    
    // String in multiple lines with tab
    tabs := `This string
        will have
        tabs in it`
    fmt.Println(tabs)
}

l
liam

你可以在内容周围加上``,比如

var hi = `I am here,
hello,
`

D
David

在 go 中,您必须非常小心格式和行距,一切都很重要,这是一个工作示例,试试吧https://play.golang.org/p/c0zeXKYlmF

package main

import "fmt"

func main() {
    testLine := `This is a test line 1
This is a test line 2`
    fmt.Println(testLine)
}

P
Prabesh P

您可以使用原始文字。例子

s:=`stack
overflow`

A
Alexis Wilke

对我来说,我需要使用 ` 重音/反引号 并且只需编写一个简单的测试

+ "`" + ...

又丑又不方便

所以我以一个字符为例:🐬 U+1F42C 来替换它

演示

myLongData := `line1
line2 🐬aaa🐬
line3
` // maybe you can use IDE to help you replace all ` to 🐬
myLongData = strings.ReplaceAll(myLongData, "🐬", "`")

https://img.shields.io/badge/Go-Playground-5593c7.svg?labelColor=41c3f3&style=for-the-badge

性能和内存评估

+ "`"replaceAll(, "🐬", "`")

package main

import (
    "strings"
    "testing"
)

func multilineNeedGraveWithReplaceAll() string {
    return strings.ReplaceAll(`line1
line2
line3 🐬aaa🐬`, "🐬", "`")
}

func multilineNeedGraveWithPlus() string {
    return `line1
line2
line3` + "`" + "aaa" + "`"
}

func BenchmarkMultilineWithReplaceAll(b *testing.B) {
    for i := 0; i < b.N; i++ {
        multilineNeedGraveWithReplaceAll()
    }
}

func BenchmarkMultilineWithPlus(b *testing.B) {
    for i := 0; i < b.N; i++ {
        multilineNeedGraveWithPlus()
    }
}

命令

去测试-v -bench=。 -run=none -benchmem 查看更多测试。B

输出

goos: windows
goarch: amd64
pkg: tutorial/test
cpu: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
BenchmarkMultilineWithReplaceAll
BenchmarkMultilineWithReplaceAll-8    12572316      89.95 ns/op   24 B/op  1 allocs/op
BenchmarkMultilineWithPlus
BenchmarkMultilineWithPlus-8          1000000000   0.2771 ns/op    0 B/op  0 allocs/op
PASS
ok      tutorial/test   7.566s

是的,+ "`" 的性能比另一个更好。


这会很慢(除非你只做一次)。使用单独的字符串并连接会更好,因为编译器可能会在编译时在文字字符串之间进行。
嗨@Alexis Wilke,感谢您的提醒。这比投反对票并且不发表任何评论的人要好得多。我添加了性能和内存评估,以根据他们的需要决定使用哪一个。
O
Ofonime Francis

对我来说,如果添加 \n 不成问题,这就是我使用的方法。

fmt.Sprintf("Hello World\nHow are you doing today\nHope all is well with your go\nAnd code")

否则,您可以使用 raw string

multiline := `Hello Brothers and sisters of the Code
              The grail needs us.
             `