out参数是ref,其值是隐式重新初始化的吗?

时间:2015-12-18 21:34:19

标签: function parameters reference d storage-class-specifier

Dlang将out参数描述为:

  

在函数输入时初始化的参数,其默认值为   它的类型。

在函数入口上使用默认值初始化参数后,它本质上只是ref吗?

import std.stdio;

void foo(out int x)
{
    writeln(x); //prints 0
    x = 2;
}

void main()
{
    int x = 1;
    writeln(x); //prints 1
    foo(x);
    writeln(x); //prints 2
} 

我没有看到任何将outref进行比较的文档 将out参数概念化为写作的快捷方式是否准确:

import std.stdio;

void foo(ref int x)
{
    x = x.init; //happens implicitly
    writeln(x); //prints 0
    x = 2;
}

void main()
{
    int x = 1;
    writeln(x); //prints 1
    foo(x);
    writeln(x); //prints 2
}

我不知道语言的复杂性,所以我担心这种印象会让我在不可预见的情况下感到悲伤。

可以在这些parameter storage classes之间做出更明确的区分,还是真的是一个自动重新初始化的参考参数?

1 个答案:

答案 0 :(得分:2)

是的,这就是今天的实施,但这并不完全是语义上的含义。

out参数视为额外的返回值而不是传统意义上的参数,你应该没问题。函数不能获取其返回值的地址,也不能通过它接收数据。不应以这些方式使用out参数。

D以前没有ref。它使用inoutinout作为参数存储类。

in意味着(并且意味着它仍然存在)您将要查看,但不会修改或存储对它的引用(后者使其与const不同 - 您可以存储const,但不能存储inscope参数,这使得编译器在理论上可以优化它们的内存分配。它仅用于数据消费。

out表示该函数将数据存储在该变量中,但不会查看或存储它。当函数将结果写入其中时,预先存在的值将丢失。编译器在函数输入时重置它以保证程序不依赖于通过它传递的某些值。

最后,旧的inout是将数据输入,并存储一个值。今天(好吧,从五年前开始),这种用法早已不复存在,inout意味着完全不同(const但返回的constness是以输入为条件的; const / immutable / mutable限定符具有与它们相同,旧的用法被ref取代,这也扩大了含义:它不再是数据输入和输出,而是对另一个变量的完整引用,这意味着你被允许做一些事情,比如拿地址。

虽然out实现为ref加上自动重新初始化,但您应该记住原始含义:您向其中写入数据但不执行任何其他操作。请勿使用其地址 - 这与ref合法(除非是scope refin ref ...),但out不正确。你应该写它,仅此而已。