[英]How should I use storage class specifiers like ref, in, out, etc. in function arguments in D?
D中的函数参数有相对多的存储类说明符,它们是:
in
(相当于const scope
) out
ref
scope
lazy
const
immutable
shared
inout
他们背后的理性是什么? 他们的名字已经提出了明显的用途。 但是,有一些悬而未决的问题:
ref
结合in
for struct
type函数参数吗? out
暗示ref
隐含? ref
是否有意义? (默认情况下,类类型是引用。) ref
? const
作为内置算术类型吗? 更一般地说:在内置类型,数组,结构,类和接口的情况下,何时以及为什么我应该使用哪个存储类说明符用于函数参数类型? (为了稍微区分问题的范围,请不要讨论shared
,因为它有其独立的含义。)
我不会默认使用。 ref
参数只接受左值,这意味着你将改变传入的参数。如果你想避免复制,那么使用const ref
或auto ref
。 但是const ref
仍然需要一个左值,所以除非你想复制你的函数,否则它通常比它的价值更令人讨厌。 而auto ref
将避免复制左值(它基本上使得它有一个函数的版本,它接受ref
的lvalues和一个不带ref
rvalues),它只适用于模板,限制了它的用处。 使用const
会产生深远的影响,因为D的const
是可传递的,并且事实上它是从变量中抛弃const
并修改它的未定义行为。 因此,虽然它通常很有用,但默认使用它可能会让你陷入困境。
使用in
为const
提供scope
,我通常建议不要使用const
。 函数参数的scope
应该使它不会引用该数据,但是对它的检查还没有正确实现,所以你实际上可以在很多情况下使用它而不是合法的。 在某些情况下, scope
是非常宝贵的(例如,使用委托,因为它使得编译器不必为它分配闭包),但对于其他类型,它可能很烦人(例如,如果传递数组是scope
,然后您无法从该函数返回切片到该数组)。 任何包含任何数组或引用类型的结构都会受到影响。 虽然你现在不会有很多关于错误使用scope
抱怨,如果你一直在使用它,你一定会在修复后遇到很多错误。 此外,它对于值类型完全没有意义,因为它们没有提到逃避。 因此, in
值类型(包括值类型的结构)上使用const
和in
实际上是相同的。
out
与ref
相同,只是它将参数重置为其init
值,这样无论传入的变量的先前状态如何,您始终都会获得相同的值。
几乎总是就函数参数而言。 当你有特定的需要时,你使用const
或scope
或whatnot,但我不建议默认使用它们中的任何一个。
当然可以。 ref
与类引用的概念是分开的。 它是对传入的变量的引用。如果我这样做的话
void func(ref MyClass obj) { obj = new MyClass(7); } auto var = new MyClass(5); func(var);
然后var将在调用func
而不是new MyClass(5)
之后引用新构造的new MyClass(7)
new MyClass(5)
。 你通过ref
传递引用。 这就像获取引用的地址(如var
)为您提供指向引用的指针而不是指向类对象的指针。
MyClass* p = &var; //points to var, _not_ to the object that var refers to.
和班级一样的交易。 ref
使参数引用传入的变量。例如
void func(ref int[] arr) { arr ~= 5; } auto var = [1, 2, 3]; func(var); assert(var == [1, 2, 3, 5]);
如果func
没有通过ref
接受它的参数,则var
将被切片,并且附加到arr
将不会影响var
。 但由于参数是ref
,所以对arr
做的任何事都是对var
。
这完全取决于你。 使它成为const
使得你不能改变它,这意味着如果你不打算改变它,你就会受到保护而不会意外地改变它。 它也可以启用一些优化,但是如果你从不写入变量,并且它是内置的算术类型,那么编译器就知道它永远不会改变,优化器应该能够进行那些优化(不管它是否确实如此)不取决于编译器的实现)。
对于几乎所有情况下的内置算术类型, immutable
和const
实际上是相同的,所以我个人认为,如果我想保证这样的变量不会改变,我只使用immutable
变。 通常,如果可以使用immutable
而不是const
则可以为您提供更好的优化和更好的保证,因为它允许跨线程隐式共享变量(如果适用),并且它始终保证变量不能被变异(而对于参考) types, const
只表示该引用不能改变对象,而不是它不能被改变)。
当然,如果你尽可能地标记你的变量const
和immutable
,那么它确实至少在某些时候帮助编译器进行优化,并且它可以更容易地捕获你不想改变的东西。 它还可以使您的代码更容易理解,因为您知道变量不会被变异。 因此,大量使用它们可能很有价值。 但同样,使用const
或immutable
可能过于严格,具体取决于类型(虽然这不是内置整数类型的问题),因此只需将所有内容自动标记为const
或immutable
就会导致问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.