Блог

МиниГо #5: Многострочный вывод

8 сентября 2024

Пятый урок мини-курса по языку программирования 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, то жду вас в комментариях.

Опубликовано 8 сентября 2024 в 15:59
Обновлено 9 сентября 2024 в 22:34
Категория: Блог
Теги:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Реклама

Связь со мной

uzabila@yandex.ru