2311ddip1000不能从函数返回域引用
原文
以下程序无法用-preview=dip1000
编译:
void main() @safe
{
int[3] a = [1, 2, 3];
int[] slice;
//好
slice = a[];
scope ref getSlice() { return slice; }
//错误:把对a局部变量的`引用`赋值给非域`getSlice()`
getSlice() = a[];
}
getSlice
应该可返回可安全地赋值给'a[]'
的引用.
如常,去掉抽象
,化简为仅指针
时,更清楚:
@safe void test()
{
int i;
scope int* p = &i;
scope ref get() { return p; }
get() = &i;
}
我不太清楚本地函数上的"域"
是否应限定环境指针或返回值
.一般,闭包环境
是DIP1000
不健全的一大根源.
这也会影响非嵌套函数
.如:
ref int* getRef(return ref scope int* p) @safe
{
return p;
}
void main() @safe
{
int n;
scope int* p;
getRef(p) = &n;
}
在没有像Rust
这样成熟的生命期
系统时,不确定接受
此代码是否可行,但尽量
,那肯定会很方便.
问题是它不认为"getRef(p)"
是"p"
变量.=
的右侧使用按值或按引用
转义的逻辑,而左侧使用只能返回
一个变量的'表达式到变量'
,因此它放弃了潜在
的多变量式
.如:
void main() @safe
{
int n;
scope int* p;
(n ? p : p) = &n;
}
错误:把"n"
局部变量的引用
赋值给非域"*(n?&p:&p)"
这可通过对左边
使用相同的按值转义
逻辑,并对一切左边
变量重复其余的checkAssignEscape
逻辑来解决.
它不会有最佳
的时间复杂度
,但复杂
的左边
式应该不多.