Interpolação de cadeias e formatos
$'Olá, {LName}!' com expressões e formatos {x:8:2}, {x:x4}, {x:n2}, enum pelo nome e datas.
O que é e por que existe#
Montar uma linha de texto com + e IntToUStr é verboso e fácil de errar. A cadeia interpolada põe a expressão dentro do texto, e cada valor é convertido pelo tipo:
WriteLn($'Olá, {LName}! Você tem {LQty} itens e {LQty * 2} no dobro.');O $ vem colado no apóstrofo. Dentro das chaves vai qualquer expressão; espaços em volta são livres.
| Escrito | Significa |
|---|---|
$'texto' | abre a cadeia interpolada |
{expr} | qualquer expressão |
{{ e }} | chaves literais (uma } solta é erro) |
'' | apóstrofo literal, como no literal comum |
Dentro de {…} os apóstrofos abrem texto (e as chaves dele não contam) e uma interpolada pode conter outra. O resultado é UString.
Como cada tipo é convertido#
| Tipo | Conversão |
|---|---|
| inteiros | IntToUStr / UIntToUStr |
Float16…Float128 | com ponto decimal (7.5) |
Currency* | com ponto decimal |
Bool8…Bool64 | texto do BoolToUStr (a RTL devolve sim/não) |
AChar, WChar | cadeia de 1 caractere |
| cadeias | como estão |
| enumerado | o nome do membro |
classe com function ToString: <cadeia> sem parâmetros | chamada virtual a ToString |
Formatos: {expr:formato}#
| Formato | Significa |
|---|---|
W e -W | a conversão normal em W colunas (à direita; - à esquerda) |
W:D | ponto fixo com D casas em W colunas (real e moeda), como o x:8:2 do Pascal |
d[P], x[P], X[P] | inteiro decimal, hexa minúsculo, hexa maiúsculo; P é o mínimo de dígitos |
f[P], e[P], n[P] | ponto fixo, científico, com vírgula de milhar (padrão 2 casas em f e n) |
g[P] | geral: o mais curto entre fixo e científico (P algarismos significativos, padrão 6) |
letra + :W | combina, como em f3:10 ou X8:-12 |
| data/hora | expressão real (Float64, TJulianDateTime) com um formato do FormatDateTime (yyyy-mm-dd hh:nn); exige uses System.Remainder |
O : só é especificador no nível 0 da expressão (fora de parênteses, colchetes, chaves e apóstrofos). Por isso um ternário vai entre parênteses: {(LQty > 40 ? 'muitos' : 'poucos')}. Decimal é sempre ponto e milhar sempre vírgula.
program InterpolacaoSaida;
// Demo 13 - Saída no console e interpolação de texto: $'...{expressão:formato}...'.
// Não há entrada interativa: aqui só mostramos como formatar o que sai.
type
TColor = (Red, Green, Blue);
var
LQty: Int32;
LPrice: Float64;
LName: UString;
LColor: TColor;
begin
LQty := 42;
LPrice := 1234.5678;
LName := 'Ana';
LColor := TColor.Green;
// Write não pula linha; WriteLn pula. Aceitam vários argumentos de tipos diferentes.
Write('Sem pular, ');
Write('e agora pulando: ', LQty, ' ', LPrice);
WriteLn;
// Formato clássico de Pascal: valor:largura:decimais.
WriteLn('[', LQty:6, '] [', LQty:-6, '] [', LPrice:10:2, ']');
// Interpolação: o texto entre {chaves} é uma expressão qualquer.
WriteLn($'Olá, {LName}! Você tem {LQty} itens e {LQty * 2} no dobro.');
// Formatos depois de ":" dentro das chaves.
WriteLn($'largura 8 : [{LQty:8}]');
WriteLn($'alinha esquerda: [{LQty:-8}]');
WriteLn($'com zeros (d5) : [{LQty:d5}]');
WriteLn($'hexa : {LQty:x} {LQty:X4} {LQty:x4}');
WriteLn($'real f2 : {LPrice:f2}');
WriteLn($'largura:casas : [{LPrice:10:1}]');
WriteLn($'milhar n2 : {LPrice * 1000:n2}');
WriteLn($'científico e3 : {LPrice:e3}');
WriteLn($'enumerado : {LColor}');
// Para escrever uma chave literal, duplique-a.
WriteLn($'chaves literais: {{LName}} = {LName}');
// Dá para usar condicional dentro (entre parênteses) e chamar funções.
WriteLn($'situação: {(LQty > 40 ? 'muitos' : 'poucos')}, maiúsculo: {UStrUpper(LName)}');
end.Sem pular, e agora pulando: 42 1234.57
[ 42] [42 ] [ 1234.57]
Olá, Ana! Você tem 42 itens e 84 no dobro.
largura 8 : [ 42]
alinha esquerda: [42 ]
com zeros (d5) : [00042]
hexa : 2a 002A 002a
real f2 : 1234.57
largura:casas : [ 1234.6]
milhar n2 : 1,234,567.80
científico e3 : 1.235e+03
enumerado : Green
chaves literais: {LName} = Ana
situação: muitos, maiúsculo: ANADemo 13. Os formatos de largura, esquerda, d5, hexa, f2, largura:casas, n2, e3, enum e chaves literais.
Uma forma de várias linhas abre com $''' seguido de fim de linha e fecha com ''' sozinho numa linha; o recuo do fecho é retirado.
Armadilhas e erros típicos#
- Em
const: a interpolada sem expressão vale (const T = $'x {{y}}';); com expressão dentro é erroFE0254("numa constante só cabe texto sem expressões"). - Tipos sem conversão:
record, vetor, ponteiro e classe semToStringnão convertem. - Arredondamento é o do
UStrFmt:1.25:f1não vira necessariamente1.3. Confira o caso que lhe interessa. - Sem localidade: não há milhar nem decimal conforme o idioma do sistema.
- Dentro das chaves, o
fc --symbolsnão gera referência a identificadores da interpolada (vale para "ir para a definição" no editor). LStringnão se mistura comUStringna mesma interpolada (a mesma queixa do+).