3

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,还是真的是自动重新初始化的 ref 参数?

4

2 回答 2

2

是的,这就是今天实现的全部内容,但这并不是它在语义上的确切含义。

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


D 以前没有ref。它使用in, out, 和inout作为参数存储类。

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

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

最后,旧的inout是将数据输入,并存储一个值。今天(嗯,从五年前开始),这种用法早已不复存在,并且inout意味着完全不同的东西(const但返回 constness 取决于输入;const/immutable/mutable 限定符的输出与它们相同)和旧的usage 被替换为ref,这也扩展了含义:它不再是数据进出,而是对另一个变量的完整引用,这意味着你可以做一些事情,比如取地址。

虽然out实现为refplus 自动重新初始化,但您应该记住原始含义:您向其写入数据但不执行任何其他操作。不要取它的地址——这对于ref(除非它是scope refin ref......)是合法的,但对于out. 你应该给它写信,仅此而已。

于 2015-12-19T03:32:33.220 回答
2

out 参数是否是一个 ref,其值被隐式重新初始化?

是的。

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

是的。

是否可以在这些参数存储类之间做出更强的区分,或者它真的是一个自动重新初始化的 ref 参数?

后者。至少,我是这么想的。我希望我没有遗漏什么。

于 2015-12-18T22:59:51.223 回答