英語版
このページの英語版を見る

補間式シーケンス

補間式シーケンス(IES)は、 文字列リテラルデータと値を交互に挿入する式である。補間式は文字列のように記述されるが、 それを受け入れる関数に直接渡される値を含むことができる。 これは、テンプレート化された関数でオーバーロードまたは処理できる式のシーケンスに変換される。

IES リテラル

InterpolationExpressionSequence:
    InterpolatedDoubleQuotedLiteral
    InterpolatedWysiwygLiteral
    InterpolatedTokenLiteral

補間式シーケンスは、WYSYWYGクォート、ダブルクォート、 トークンリテラルのいずれかである。ダブルクォートリテラルのみ、エスケープを挿入することができる。

文字列リテラルとは異なり、IES リテラルには 文字列式の文字型幅を定義する接尾辞を付けることはできない。

ダブルクォートで囲まれたIESリテラル

InterpolatedDoubleQuotedLiteral:
    i" InterpolatedDoubleQuotedCharactersopt "
InterpolatedDoubleQuotedCharacters: InterpolatedDoubleQuotedCharacter InterpolatedDoubleQuotedCharacter InterpolatedDoubleQuotedCharacters
InterpolatedDoubleQuotedCharacter: DoubleQuotedCharacter InterpolationEscapeSequence InterpolationExpression
InterpolationEscapeSequence: EscapeSequence \$
InterpolationExpression: $( AssignExpression )

DoubleQuotedStringと同様に、二重引用符で囲まれたIESリテラルは エスケープ文字を含むことができる。通常のエスケープ機能に加え、 リテラル $ をエスケープする機能も追加された

左括弧以外の任意の文字に続く $ は、 式内ではリテラル $ として扱われるため、エスケープする必要はありません。

InterpolationExpression内の式は完全なD 式であり、その部分ではエスケープは不要である。

Wysiwyg IES リテラル

InterpolatedWysiwygLiteral:
    i` InterpolatedWysiwygCharactersopt `
InterpolatedWysiwygCharacters: InterpolatedWysiwygCharacter InterpolatedWysiwygCharacter InterpolatedWysiwygCharacters
InterpolatedWysiwygCharacter: WysiwygCharacter InterpolationExpression

Wysiwyg(「What You See Is What You Get」)のIESリテラルは、 WysiwygString文字列と同様に定義されるが、バッククォート構文のみをサポートする。 これらのリテラル内ではエスケープは認識されない。

トークンIESリテラル

InterpolatedTokenLiteral:
    iq{ InterpolatedTokenStringTokensopt }
InterpolatedTokenStringTokens: InterpolatedTokenStringToken InterpolatedTokenStringToken InterpolatedTokenStringTokens
InterpolatedTokenStringToken: InterpolatedTokenNoBraces { InterpolatedTokenStringTokensopt }
InterpolatedTokenNoBraces: TokenNoBraces InterpolationExpression

TokenStringと同様に、IES トークンリテラルには有効な D トークンのみを含める必要がある。 ただし、InterpolationExpression は例外である。 エスケープは認識されない。

式の翻訳

インターポレーション式シーケンスをレキシコンが検出すると、トークンは 式のシーケンスに変換され、単一のトークンが置き換えられる。 このシーケンスは常に式core.interpolation.InterpolationHeader() で始まり、常にcore.interpolation.InterpolationFooter()

トークンのリテラル文字列データである各部分str は、 式に変換される。core.interpolation.InterpolatedLiteral!(str)

インターポレーション式であるトークンの各部分$(expr) は、core.interpolation.InterpolatedExpression!(expr), expr というシーケンスに変換される。

// std.typeconsの単純版。Tuple
struct Tuple(T...) { T value; }
Tuple!T tuple(T...)(T value) { return Tuple!T(value); }

import core.interpolation;
string name = "John Doe";
auto items = tuple(i"Hello, $(name), how are you?");
assert(items == tuple(
    InterpolationHeader(),                       // IESの開始を表す
    InterpolatedLiteral!("Hello, ")(),           // リテラル文字列データ
    InterpolatedExpression!("name")(),           // 式リテラルデータ
    name,                                        // 直接渡される式
    InterpolatedLiteral!(", how are you?")(),    // リテラル文字列データ
    InterpolationFooter()));                     // IESの終了を表す

core.interpolation 型

core.interpolation で定義されている型は、IES を使用するためにインポートする必要はない。 IES を使用する際には、これらの型は自動的にインポートされる。これらの型は、 コンパイル時に IES を簡単に内省して処理できるように定義されている。

InterpolationHeader と InterpolationFooter

InterpolationHeader 型およびInterpolationFooter 型は、 IESを処理するための関数のオーバーロードを容易にする空の構造体である。また、 式リストのどの部分がIES経由で渡されたかを理解するためにも使用できる。

これらの型には、toString 定義があり、空文字列を返す。 これにより、IESをテキストに変換する関数による処理が可能になる。例えば、 std.stdio.writelnまたは std.conv.text

InterpolatedLiteral

InterpolatedLiteral 型は空の構造体であり、 IESの文字列リテラル部分へのコンパイル時のアクセスを提供する。この型はまた、toString メンバ関数も提供し、 この値が置き換えたシーケンスの部分を返す。

InterpolatedExpression

InterpolatedExpression 型は空の構造体であり、 以下の式を生成するために使用されたリテラルへのコンパイル時のアクセスを提供する。 この型は、空文字列を返すtoString メンバ関数を提供する。 また、この型にはenum expression メンバがあり、これは この型を構築するために使用されたテンプレートパラメータと等しい。

string name = "John Doe";
auto ies = i"Hello, $(name)";
static assert(is(typeof(ies[0]) == InterpolationHeader));
static assert(ies[1].toString() == "Hello, ");
static assert(ies[2].expression == "name");
assert(ies[3] == name);
static assert(is(typeof(ies[4]) == InterpolationFooter));

IESの受け入れと処理

IES を受け入れるための推奨されるメカニズムは、シーケンス内のさまざまなパラメータに一致する可変長引数テンプレート関数を提供することである。 この関数は、 明示的なInterpolationHeader およびInterpolationFooter パラメータで囲まれている。

void processIES(Sequence...)(InterpolationHeader, Sequence data, InterpolationFooter)
{
    // ここで`data`を処理する
}

IESは、補間式として型も含むことができる。これは、 可変長のテンプレートパラメータに渡すことで使用できる。

template processIESAtCompileTime(InterpolationHeader header, Sequence...)
{
    static assert(Sequence[$-1] == InterpolationFooter());
}

alias result = processIES!i"Here is a type: $(int)";

文字列への変換

多くの場合、IES をstring に変換することが望ましい。 Phobos 関数 std.conv.textIES をstring に変換し、 文字列が必要なあらゆるコンテキストで使用することができます。例えば、文字列変数に代入したり、文字列を受け入れる関数を呼び出したりする場合などです。

import std.conv : text;
string name = "John Doe";

string badgreeting = i"Hello, $(name)"; // エラー
string greeting = i"Hello, $(name)".text; // OK
assert(greeting == "Hello, John Doe");

IESを受け取ることを希望するライブラリ作成者には、std.conv に依存するのではなく、IESを受け取るオーバーロードを提供することを強く推奨する。 これは、不必要な割り当てが発生するためである。これは、特定の 型の注入攻撃が、悪意のあるユーザー提供データから可能である場合に特に重要である。