0
点赞
收藏
分享

微信扫一扫

d,cast转换aa为右值


​​原文​​ 测试用例:

shared int[int] aa;
void main () {
cast()aa[1] = 1;//违反区间
}

原来工作正常.
你正在​​​aa[1]​​​上抛弃​​共享​​​.该表达式是​​访问值​​​,而不是​​赋值​​​.与定义​​opIndex​​​和​​opIndexAssign​​​的结构(表达式调用​​opIndex​​​,而不是​​opIndexAssign​​​)是一致的.
如果使用​​​cast()(aa[1])=1​​​,即使在旧版本上也会出现区间错误.为何曾经​​奏效​​?

我认为旧编译器解析其为​​也适合​​​新​​编译器​​​且无区间错误的​​(cast()aa)[1]​​​.
本例,​​​aa​​​也是​​immutable​​​.我知道​​使它​​​工作的​​唯一方法​​现在非常丑陋(丢弃不变也许就该丑?):

shared immutable int[int] aa;
void main () {
// (cast()aa)[1] = 1; // 无不变仍工作,
(*cast(int[int]*)(&aa))[1] = 1;//这样?
}

有​​静态共享构造器​​:

shared static this()
{
aa[1] = 1; /*不必强制转换*/
}

但这样不行的:

void f() {
aa[1] = 1; // 错误
}
shared static this()
{
f();//f仍然是模板,模板插件,仍不管用
//在f嵌套函数中不能初化aa不变量
}

如果可在​​pure​​​函数中构建​​数组​​的可变版本,则可这样做:

int[int] make_aa() pure
{
int[int] maa;
maa[1] = 1; /*或函数调用等等*/
return maa;
}
immutable int[int] aa;
shared static this()
{
aa = make_aa();
}

如果不能在​​pure​​​函数中这样,则可用​​cast​​​来这样:​​aa=cast(immutable)make_aa();​​​.
从​​​可变​​​转换为​​不变​​​更好,因为无​​未定义行为​​​(只要以后不使用​​可变​​​引用).丢弃​​不变​​​,然后​​修改​​​,确实有​​未定义行为​​.


举报

相关推荐

0 条评论