学习Golang中的多线字符串(附代码)

488 阅读6分钟

学习Golang中的多线字符串

Go的字符串字元

字符串表示 "字符串常量",即 Go 源文件中不可改变的字符串值。

在Go中,有两种声明字符串字面的方法:使用引号和使用反斜线。前者声明的是 "解释的字符串",后者声明的是 "原始字符串"。还有一种 "符文字元",它并不是正确的字符串,而是代表一个字符。

解释的字符串

在双引号(")之间声明的字符串字头是一个解释的字符串。

解释型字符串的特点是。

  • 它们可以跨越源文件中的一个行。
  • 它们可以包含任何字符,除了 "原始 "换行符或未转义的双引号。
  • 反斜线转义是被解释的。

例子:

"foo"                  // The word foo
"foo\nbar"             // foo, newline, and bar
"Saudações"            // UTF-8 text
"Sauda\u00E7\u00F5es"  // Unicode code points (same text as above)

原始字符串

在反斜线(又称 "反引号")之间声明的字符串字面是一个原始字符串。它有这些特点:

  • 它可以跨越源代码中的多行。
  • 源文件中的原始换行符成为字符串常量中的换行符。
  • 它不解释转义序列。
  • 它不能包括反斜线(甚至不能通过转义,见上文)。

符文字元

引用Go的文档,"符文字元代表一个符文常数,一个识别Unicode码位的整数值"。从概念上讲,它代表一个单一的字符(请记住,这是Unicode)。

符文字面也可以解释反斜杠转义。

例子:

'a'
'ã'
'\t'
'\377'
'\xff'
'\u12e4'
'\U00101234'

Go源代码中的ASCII艺术

我想从我的第一个Go程序中打印的ASCII艺术,大量使用了各种符号,如反斜线(`)、单引号(')和反斜线(\)。当然,它也有多行。

在源文件中,我有几个选择来表示它:

  1. 在双引号之间。我需要把它分解成多个字符串常量(每行一个),并转义反斜杠和双引号字符。这样做是可以的,但在源文件中会显得很扭曲。
  2. 一个很长的单行解释脚本,并转义了换行字符。这很不方便。
  3. 在反斜线之间。我有一个单一的多行字符串,我不需要转义什么。但是我不能在字符串本身中使用反斜线。

另一个选择当然是不将字符串嵌入Go源文件中,但这超出了本练习的目标。事实上,这个练习是相当聪明的,因为它迫使我学习了很多关于Go中的字符串字面的知识。

我决定采用选项3--反斜线--主要是因为如果没有转义的话,嵌入的字符串在Go源文件中看起来更好。我妥协了,在ASCII艺术中用反斜线代替了反符号字符。

这就是我的最终结果:

package main

import (
  "fmt"
)

func main() {
  // Credit: unknown artist.
  fmt.Println(`    888888888888888888888
  s 88 ooooooooooooooo 88     s 888888888888888888888888888888888888888
  S 88 888888888888888 88    SS 888888888888888888888888888888888888888
 SS 88 888888888888888 88   SSS 8888                         - --+ 8888
 SS 88 ooooooooooooooo 88  sSSS 8888           o8888888o         | 8888
sSS 88 888888888888888 88 SSSSS 8888         o88888888888o         8888
SSS 88 888888888888888 88 SSSSS 8888        8888 88888 8888      | 8888
SSS 88 ooooooooooooooo 88 SSSSS 8888       o888   888   888o       8888
SSS 88 888888888888888 88 SSSSS 8888       8888   888   8888       8888
SSS 88 888888888888888 88 SSSSS 8888       8888   888   8888       8888
SSS 88 oooooooooo      88 SSSSS 8888       8888o o888o o8888       8888
SSS 88 8888888888 .::. 88 SSSSS 8888       988 8o88888o8 88P       8888
SSS 88 oooooooooo :::: 88 SSSSS 8888        8oo 9888889 oo8        8888
SSS 88 8888888888  \'  88 SSSSS 8888         988o     o88P         8888
SSS 88ooooooooooooooooo88  SSSS 8888           98888888P           8888
SSS 888888888888888888888__SSSS 8888                               8888_____
SSS |   *  *  *   )8c8888  SSSS 888888888888888888888888888888888888888
SSS 888888888888888888888.  SSS 888888888888888888888888888888888888888
SSS 888888888888888888888 \_ SSsssss oooooooooooooooooooooooooooo ssss
SSS 888888888888888888888  \\   __SS 88+-8+-88============8-8==88 S
SSS 888888888888888888888-. \\  \  S 8888888888888888888888888888
SSS 888888888888888888888  \\\  \\       \.__________.'      \ .
SSS 88O8O8O8O8O8O8O8O8O88  \\.   \\______________________________\_.
SSS 88 el cheapo 8O8O8O88 \\  '.  \|________________________________|
 SS 88O8O8O8O8o8O8O8O8O88  \\   '-.___
  S 888888888888888888888 /~          ~~~~~-----~~~~---.__
 .---------------------------------------------------.    ~--.
 \ \______\ __________________________________________\-------^.-----------.
 :'  _   _ _ _ _  _ _ _ _  _ _ _ _   _ _ _           \\        \
 ::\ ,\_\,\_\_\_\_\\_\_\_\_\\_\_\_\_\,\_\_\_\           \      o '8o 8o .
 |::\  -_-_-_-_-_-_-_-_-_-_-_-_-_-___  -_-_-_   _ _ _ _  \      8o 88 88 \
 |_::\ ,\_\_\_\_\_\_\_\_\_\_\_\_\_\___\,\_\_\_\,\_\_\_\_\ \      88       \
    \:\ ,\__\_\_\_\_\_\_\_\_\_\_\_\_\  \,\_\_\_\,\_\_\_\ \ \      88       .
     \:\ ,\__\_\_\_\_\_\_\_\_\_\_\_\____\    _   ,\_\_\_\_\ \      88o    .|
       :\ ,\____\_\_\_\_\_\_\_\_\_\_\____\  ,\_\ _,\_\_\_\ \ \      'ooooo'
        :\ ,\__\\__\_______________\__\\__\,\_\_\_\,\___\_\_\ \
         \\  --  -- --------------- --  --   - - -   --- - -   )____________
           \--------------------------------------------------'
`)
}

经验之谈

Go提供了3种表示字符串或字符字面的方法:

语法符号跨度转义
解释的字符串双引号 (")单一来源行
原始字符串反斜线 (`)多个源行
符文字元单引号 (')单一代码点是的

关于围棋中的字符串,你还有什么要指出的?