d

¿Diferencia entre ''const ref'' y ''in''?



(2)

  1. No es legal que los parámetros de scope escapen a la función. Se supone que el compilador garantiza que no haya referencias a esos datos que escapen a la función. Se usa principalmente con delegados, ya que permite que el compilador evite asignar un cierre, ya que sabe que el delegado no escapará.

  2. const ref is const (igual que in , pero la variable se pasa por referencia en lugar de copiarse, por lo que se evita una copia. Sin embargo, a diferencia de C ++, la const ref no funciona con valores. Se le debe dar un valor. Por lo tanto, si declara que un parámetro es const ref , será limitante en lo que puede pasarle. En general, tendrá que declarar una variable para pasarle, mientras que in aceptará una temporal.

    void func(const ref int var) {} int a; func(a); //legal func(7); //illegal

Ambas llamadas serían legales si la func tomara const o in . Entonces, en general, la pregunta no es si debe usar const ref o const ref in . La pregunta es si debes usar const o in . Y en ese caso, la pregunta es si desea usar el scope o no, ya que ambos son const . Y usa el scope si quiere asegurarse de que ninguna referencia a la variable que pase se escape a esa función, por lo que generalmente solo se usa con delegados, pero podría ser útil con clases o matrices.

Sin embargo, pure en una función garantiza que ninguna referencia a ninguno de sus argumentos puede escapar excepto a través del valor de retorno (ya que pure funciones pure solo pueden usar variables globales si son inmutables o son tipos de valor y son const), por lo que pure generalmente le da Todo lo que necesitas para los parámetros que son clases y matrices. Además, si el tipo de retorno es una clase o una matriz, generalmente no desea que los argumentos no puedan escapar, porque entonces, en lugar de poder reutilizar cualquier cosa de esos argumentos en el valor de retorno, la función Se obliga a hacer una copia, que generalmente es menos eficiente.

Por lo tanto, el scope generalmente solo se usa con delegados, pero en ocasiones es útil con clases o arreglos. En general, es preferible que las funciones sean pure todos modos, por lo que se encarga de la mayor parte del problema. Como tal, si bien no se pierde nada con el uso, a menudo hay poco sentido de usar in lugar de const . Y generalmente solo usa la const ref si realmente quiere evitar copiar la variable que se pasa, porque de lo contrario solo puede pasar valores a esa función. Puede sobrecargar una función de tal manera que tenga una versión que tome const y una que tome const ref , pero que obviamente dé como resultado la duplicación de código, así que a menos que realmente desee const ref , probablemente sea mejor usar const .

EDITAR:

scope aún no se ha implementado para nada que no sean delegados (a partir del 2013-06-18), por lo que es desaconsejable utilizar cualquiera de los scope o con cualquier otra cosa que no sean delegados. En este momento, son engañosos, y si / una vez que se implementa el scope para algo más que delegados, existe un alto riesgo de que su código se rompa debido a las referencias a las variables marcadas con scope o in escape.

Estoy tratando de entender la diferencia entre la const ref y la const ref , especialmente cuando se trata de rendimiento.

  1. Sé que in es equivalente a const scope , pero lo que hace the scope storage class means that references in the parameter cannot be escaped (eg assigned to a global variable). ¿media? código de ejemplo es bienvenido.

  2. ¿Cómo decido entre const ref y cuando implemento una función? Sé que con ref el objeto no se copia porque es una referencia, pero ¿es lo mismo con in ?


1) la clase de almacenamiento de parámetros de scope significa que no se le permite escapar de una referencia al parámetro. Ejemplo:

Object glob; struct S { Object o; void foo(scope Object o) { this.o = o; // Not allowed! ''o'' must not be escaped glob = o; // ditto } }

Tenga en cuenta que DMD no es muy bueno para detectar esto. El ejemplo anterior actualmente compila, pero no está permitido.

scope es más útil para los parámetros de delegado:

void foo(scope void delegate() dg) { /* use dg */ } void main() { int i; foo({ ++i; }); }

En el ejemplo anterior, no es necesario asignar un cierre para la función anónima a pesar de que tiene un valor superior, porque foo "garantiza" (es el trabajo del compilador ...) que el delegado no se escape. DMD actualmente implementa esta optimización.

2) Creo que la idea es que cuando se usan tanto const como scope , el compilador podría pasar teóricamente por referencia o valor a voluntad, razón por la cual el método abreviado es útil. DMD no se aprovecha de esto en este momento, pero es un atajo útil y tiene algún valor de documentación.

En resumen, actualmente no obtendrá ningún rendimiento a menos que se use en un delegado. ref puede obtener algo de rendimiento con estructuras grandes o matrices estáticas. Cuando la ref se utiliza por motivos de rendimiento, a menudo se utiliza const para documentar (y aplicar) que la ref no se utiliza para actualizar el valor original.