Как распечатать строковое представление объекта в D? - PullRequest
3 голосов
/ 18 октября 2010

Я хотел бы сделать что-то эквивалентное Python repr:

>>> x = "a\nb\nc"

>>> print x
a
b
c
>>> repr(x)
"'a\\nb\\nc'"

>>> print repr(x)
'a\nb\nc'

Как я могу сделать это в D?Существует ли директива формата, похожая на %r?

редактора Python: я хочу иметь возможность печатать строки в их экранированном виде для целей отладки (я только начал изучать D и пишу глупый текстфункции обработки).

Ответы [ 4 ]

2 голосов
/ 18 октября 2010

В D строки не являются объектами, и когда вы используете escape-символы, вы на самом деле сохраняете символ, а не сам escape (что, как я ожидаю, делал и Python).Поэтому, если вы хотите преобразовать строку в ее экранированную форму, вам нужно изменить вывод самостоятельно (я не знаю какой-либо библиотечной функции для этого).

В противном случае объекты могут переопределить функцию toString (), котораядолжен создать строковое представление объекта.

Обновление: вот пример repr в D. Но обратите внимание, поскольку исходный текст нигде не сохраняется в исполняемом файле, он также преобразует литеральные представления.Не должно быть проблем с Unicode, поскольку нормальная целостность строки не повреждена.

import std.stdio;
import std.exception;

void main() {
    writeln(repr("This\nis\n\t*My\v Test"));
}

string repr(string s) {
    char[] p;
    for (size_t i; i < s.length; i++)
    {
        switch(s[i]) {
            case '\'':
            case '\"':
            case '\?':
            case '\\':
                p ~= "\\";
                p ~= s[i];
                break;
            case '\a':
                p ~= "\\a";
                break;
            case '\b':
                p ~= "\\b";
                break;
            case '\f':
                p ~= "\\f";
                break;
            case '\n':
                p ~= "\\n";
                break;
            case '\r':
                p ~= "\\r";
                break;
            case '\t':
                p ~= "\\t";
                break;
            case '\v':
                p ~= "\\v";
                break;
            default:
                p ~= s[i];
                break;
        }
    }

    return assumeUnique(p);
}
1 голос
/ 18 октября 2010

Стандартная библиотека D не содержит такой функции, но написать ее тривиально.Просто пройдите строку и замените все вхождения "\n" на "\\n" и т. Д.

1 голос
/ 18 октября 2010

Строки обрабатываются и escape-последовательности заменяются во время компиляции. Во время выполнения информация теряется, и вам нужно будет отменить экранирование самостоятельно (возможно, уже есть какая-то стандартная экранирующая функция), но она не встроена.

Если вы контролируете источник, вы можете использовать необработанные строки . Просто поставьте r перед вашей строкой.

"a\tb" => "a    b"
r"a\tb" => "a\tb"
1 голос
/ 18 октября 2010

D имеет два способа объявить строки WYSIWYG:

r"thestring"
`thestring`

Итак, следующая программа

import std.stdio;

void main()
{
    auto a = r"hello\nworld";
    auto b = `hello\nworld`;

    writeln(a);
    writeln(b);
}

печать

hello\nworld
hello\nworld

Однако, если у вас есть произвольная строка, а не строковый литерал, и вы хотите иметь возможность печатать ее с символами новой строки и тому подобным, которые будут напечатаны как их escape-последовательности, вам придется выполнить некоторую обработку строк - скорее всего, с помощью std.string.replace() для замены каждого символа его escape-последовательностью на дополнительные обратные косые черты. Например, чтобы избежать перевода строки, вы должны сделать следующее:

str.replace("\n", "\\n");

Но вам придется делать это индивидуально для '\ t', '\ r', '\' и т. Д. Я не знаю ни одного способа сделать это автоматически. Строки WYSIWYG позволяют вам избежать необходимости использовать все дополнительные обратные слеши при построении строки.

...