Пятый урок мини-курса по языку программирования Go (Golang) в котором мы поговорим про многострочные строки и как с ними работать в Го.
Первым заданием на курсе Codecademy «Learn Go» идет создание программы, которая печатает ASCII-рисунки. От программы «Hello, World» она отличается тем, что должна выводить несколько строк. Это отличная возможность узнать, как в Go могут быть представлены многострочные строки.
Строковые литералы 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, — «рунный литерал представляет собой рунную константу, целочисленное значение, идентифицирующее точку кода Юникода». Концептуально он представляет собой один символ (учитывая, что это Юникод).
Рунные литералы также интерпретируют эскейпы обратного слеша.
Примеры:
'a'
'ã'
'\t'
'\377'
'\xff'
'\u12e4'
'\U00101234'
ASCII-арт в исходном коде Go
В ASCII-арте, который я хотел вывести из своей первой программы на Go, свободно использовались всевозможные символы, такие как обратные кавычки (`), одинарные кавычки (‘) и обратные слеши (\). Разумеется, в ней также было несколько строк.
У меня было несколько вариантов представления этого в исходном файле:
- Между двойными кавычками. Мне нужно разбить его на несколько строковых констант (по одной на строку) и экранировать символы обратной косой черты и двойных кавычек. Это сработает, но будет выглядеть искаженно в исходном файле.
- Очень длинный, однострочный интерпретируемый скрипт с экранированными символами новой строки. Это громоздко.
- Между обратными кавычками. У меня будет одна многострочная строка, и мне не нужно будет ничего экранировать. Но я не смогу использовать обратные кавычки в самой строке.
Другой альтернативой, конечно, было бы не встраивать строку в исходный файл 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 способа представления строковых или символьных литералов:
Синтакс | Символ | Span | Экранирование |
---|---|---|---|
Interpreted strings | double quotes (" ) |
Single source line | Yes |
Raw strings | backticks (` ) |
Multiple source lines | No |
Rune literals | single quotes (' ) |
Single code point | Yes |
Если вам есть что добавить о строках в Go, то жду вас в комментариях.