2501d,d的插值式

原文

插值式序列

插值式序列(IES)是散布串字面数据和值的式.插值式类似串编写.
可重载或由模板函数处理的序列转换它.
IES字面

InterpolationExpressionSequence:
    InterpolatedDoubleQuotedLiteral
    InterpolatedWysiwygLiteral
    InterpolatedTokenLiteral

插值式序列可以是所见即所得引号,双引号或令牌字面.只有双引号字面才能包含转义符.

串字面不同,IES字面不能有定义串式符类型宽度后缀.

双引号IES字面

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

双引号串一样,双引号IES字面中可包含转义符.在普通转义添加的还有转义字面$的能力

中,除左括号以外的符$都按字面$对待,无需转义它.

插值式中的完整的D式,式的该部分不需要转义.

所见即所得的IES字面

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

所见即所得IES字面的定义类似所见即所得的串,但仅支持反引号语法.这些字面中不会识别转义.

令牌IES字面

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

令牌串一样,IES令牌字面必须仅包含有效D令牌,但插值式除外.不会识别转义.

翻译式

词法分析器遇见插值式序列时,按替换单个令牌的式序列转换该令牌.序列总是以core.interpolation.InterpolationHeader()式开头,总是以core.interpolation.InterpolationFooter()结尾.
core.interpolation.InterpolatedLiteral!(str)式转换令牌的每个部分(即字面串数据)
core.interpolation.InterpolatedExpression!(expr),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处理.

插值头插值脚

插值头插值脚类型是允许轻松重载函数以处理IES空结构.还可用它们来理解式列表哪些部分是通过IES传递的.

这些类还有返回空串toString定义,以允许按文本转换IES的函数(如std.stdio.writelnstd.conv.text)处理.

插值字面

插值字面类型是一个编译时访问IES串字面部分空结构.它还有个返回此值替换的序列部分toString成员函数.

已插值式内插式

已插值式类型是一个对以下式编译时访问字面空结构.它提供了一个返回空串toString成员函数.

它还有一个用来构造类型参数的枚举式成员.

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推荐机制是提供变参模板函数来匹配显式插值头插值脚参数包围的序列内的各种参数.

void processIES(Sequence...)(InterpolationHeader, Sequence data, InterpolationFooter)
{
    //在此处处理`'数据'`
}

IES还可按插值式包含类型.可通过传递给变参模板参数来使用它.

template processIESAtCompileTime(InterpolationHeader header, Sequence...)
{
    static assert(Sequence[$-1] == InterpolationFooter());
}
alias result = processIES!i"Here is a type: $(int)";

String转换

许多时候,需要按串转换IES.Phobos函数std.conv.text可在需要串的环境按串转换IES来用,如赋值给串变量,或调用接受串的函数.

import std.conv : text;
string name = "John Doe";
string badgreeting = i"Hello, $(name)";
    //错误
string greeting = i"Hello, $(name)".text;
    //好
assert(greeting == "Hello, John Doe");

强烈建议想接受IES库作者提供接受它们的重载,而不是依赖std.conv,因为这会导致不必要的赋值.当某些类型的注入攻击可能来自恶意用户提供的数据时,它尤其重要.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值