天天看点

d递归和属性推导

​​原文​​ 我遇见歧义了.

float recurse()(float val, float till)
{
    return val < till? recurse(val * 2, till): val;
}

@safe void main()
{
    import std;

    writeln(recurse(1.5, 40.0));
    writeln(typeid(&recurse!()));
}
//编译并打印:
48
float function(float, float) pure nothrow @nogc @safe*      

但​

​规范​

​​说,不会按​

​@安全或纯及不抛​

​​推导​

​递归​

​​函数.

​​

​实现​

​​和​

​规范​

​,哪个对?

我倾向​

​实现​

​​是正确的,因为​

​代码​

​​并没有违反​

​内存安全​

​​.

​​

​丹尼斯​

​​正在研究使​

​@安全​

​​推导对​

​递归​

​​函数也是正确的,所以未来可能会完全​

​取消​

​该限制.

当​

​函数​

​​直接调用​

​自身​

​​时,忽略对​

​该调用​

​​的属性​

​检查​

​​.

然而,当​​

​两者​

​​间有​

​多个​

​​函数时,​

​推导​

​​就会变成"我正在调用现在​

​不能完成属性推导​

​​函数,所以​

​保守​

​​地假设不能按​

​@安全​

​​推导所有​

​属性​

​​.",似乎​

​规范​

​​已修改为​

​记录​

​​实现的​

​该缺点​

​.

我希望​

​可简单​

​​地假定已​

​推导​

​所有属性,使如下工作:

void fun1()() { fun2(); }
void fun2()() { fun1(); }

void main() @safe pure nothrow @nogc
{
    fun1(); // 当前失败
}      

但这里有个​

​更麻烦​

​情况:

@system void systemFunc();

void fun1()()
{
    alias T = typeof(fun2());
    systemFunc();
}

void fun2()()
{
    fun1();
}

void main0() @system
{
    fun1();
}

void main() @safe
{
    fun2(); // 非系统!
}      

编译器分析​

​fun1​

​​,然后​

​fun2​

​​,然后需要决定调用​

​fun1​

​​是否是​

​安全​

​​的.

如果它假定为​​

​是的,安全​

​​.则稍后当它看到调用​

​系统函数(systemFunc)()​

​​时,需要​

​返回​

​​并标记​

​函数2()​

​​为​

​@系统​

​​,并​

​重新分析​

​​,​

​T​

​​现在是​

​@系统​

​​的​

​fun1​

​​.

​​

​DMD​

​​不适合做​

​该回溯​

​​,会非常慢,所以​

​一般​

​​不会​

​修复​

​.