我试图理解之间的区别const ref和in,特别是当它涉及到性能.
我知道这in相当于const scope,但是什么the scope storage class means that references in the parameter cannot be escaped (e.g. assigned to a global variable).意思?示例代码是受欢迎的.
如何在实现功能之间const ref和之间做出决定in?我知道ref对象不会被复制,因为它是一个引用,但是同样如此in?
jA_*_*cOp 11
1)scope参数存储类意味着不允许转义对参数的引用.例:
Object glob;
struct S
{
Object o;
void foo(scope Object o)
{
this.o = o; // Not allowed! 'o' must not be escaped
glob = o; // ditto
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,DMD不是很擅长检测这一点.上面的示例目前正在编译,但不允许.
scope 对委托参数最有用:
void foo(scope void delegate() dg)
{
/* use dg */
}
void main()
{
int i;
foo({ ++i; });
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,即使它具有upvalue,也不需要为匿名函数分配闭包,因为foo"保证"(编译器的工作......)代理没有被转义.DMD目前确实实现了这种优化.
2)我认为这个想法是,当使用const和scope使用时,编译器理论上可以随意通过引用或值传递,这就是in快捷方式有用的原因.DMD现在没有利用这一点,但它仍然是一个方便的捷径,它有一些文档价值.
简而言之,in除非在代表身上使用,否则目前不会获得任何表现.ref 可以通过大型结构或静态数组获得一些性能.当ref用于性能原因,const往往是用来记录(和执行)将ref是不用于更新原有的价值.
Jon*_*vis 11
scope参数逃脱该功能是不合法的.编译器应该保证不会对该数据的引用转义该函数.它主要用于委托,因为它允许编译器避免分配闭包,因为它知道委托不会转义.
const ref是const- 就像in将 - 但变量是通过引用传递而不是被复制,所以你避免复制.但是,与C++不同, const ref它与rvalues 不兼容.必须给它一个左值.因此,如果您声明一个参数const ref,那么它将限制您传递给它的内容.你通常必须声明一个变量传递给它,而in接受一个临时变量.
void func(const ref int var) {}
int a;
func(a); //legal
func(7); //illegal
Run Code Online (Sandbox Code Playgroud)如果func采取const或,这两个电话都是合法的in.所以,一般来说,问题不在于你是否应该使用const ref或in.问题是你是否应该使用const或in.在这种情况下,问题是你是否要使用scope,因为它们都是const.而你使用scope,如果你想确保变量没有提到你通过将逃脱的功能,所以它一般只与代表使用,但可以使用类或阵列有用.
然而,pure在功能保证任何它的参数没有引用可以除了通过返回值逃生(因为pure函数只能使用全局变量,如果他们是不可变的或都是值类型,并常量),所以pure一般给你所有你需要类和数组的参数.此外,如果返回类型是一个类或数组,你一般不想让这个论点无法逃避,因为再不是能够重新使用这些参数中的任何返回值,函数被迫制作副本,这通常效率较低.
因此,scope通常只与代理一起使用,但有时对类或数组很有用.pure无论如何,功能通常都是优选的,因此可以解决大部分问题.因此,尽管使用它并没有什么坏处in,但使用in而不是使用它几乎没什么意义const.而且通常只有const ref在你真的想避免复制传入的变量时才使用,否则你只能将lvalues传递给该函数.你可以重载一个函数,使它具有const一个需要的版本和一个需要的版本const ref,但这显然会导致代码重复,所以除非你真的想要const ref,否则最好使用它const.
编辑:
scope尚未实施除代表以外的任何其他事项(截至2013-06-18),因此使用其中任何一项scope或in与代表以外的任何其他事项都是不明智的.目前,他们是误导性的,如果一旦/ scope是比代表以外的任何实现,有一个高风险,你的代码将打破由于标有变量的引用scope或in逃逸.