delphi uses-clause

delphi - Agregar una unidad a la interfaz usa una cláusula en lugar de la cláusula de uso de Implementación



uses-clause (5)

El IDE también usa cómo usted declara sus usos para determinar lo que necesita compilar.

Si su sección de interfaz usa UnitA y su sección de implementación usa UnitB, entonces, si la unidad B necesita recompilar, su unidad no lo hará, pero si la unidad A cambia, entonces su unidad necesitará ser recompilada.

Es uno de los secretos de la velocidad de compilación súper rápida de Delphis.

En cuanto a su ejecutable terminado, espero que tenga el mismo tamaño donde quiera que coloque las declaraciones (el enlazador es inteligente y solo enlaces en métodos, etc. que realmente usa su aplicación), pero la ubicación real de varias fuentes haría casi sin duda cambiará si se cambia el orden de las declaraciones de la unidad.

Cuando uso Delphi: si tengo una unidad que está llena de constantes como ...

Unit AConsts; Interface Const Const1 : WideString = ''Const1''; Const2 : WideString = ''Const2''; Const3 : WideString = ''Const3''; Const4 = 100; Const5 = 100; Implementation end.

y quiero usar esta unidad desde otra unidad, ¿hay alguna diferencia entre ...

Unit AUnit; Interface Uses AConsts; Implementation end.

y

Unit AUnit; Interface Implementation Uses AConsts; end.

? O en otras palabras, ¿hay alguna diferencia entre los dos en lo que respecta a una aplicación compilada?

[Editar 1]

Gracias por las respuestas hasta ahora.

No hice esta pregunta lo suficientemente clara, y por eso me disculpo. La pregunta no es sobre el alcance, evitar referencias circulares, etc. Se trata de diferencias en la aplicación compilada. Tal vez otro ejemplo ayudaría.

Si UnitA, UnitB y UnitC usan AConsts, habría una diferencia en la aplicación compilada (suponiendo que no haya conflictos de nombres entre las constantes en las unidades AConsts y otro código) entre App1 donde estas UnitA, UnitB y UnitC tienen todos aconsts en la interfaz cláusula de usos de la sección y App2 donde UnitA, UnitB y UnitC tienen elementos en la cláusula de usos de la sección Implementación.


La diferencia tiene que ver con dónde se le permite referirse a las cosas que AConsts tiene en su sección de interfaz. En el primer AUnit , puede usar Const4 para declarar un conjunto de tamaño fijo en esa sección de interfaz. No podría hacer eso en el segundo AUnit porque Const4 no está dentro del alcance.

Puede tener un efecto en el programa compilado, si no tiene cuidado. Supongamos que tenemos otra unidad que también declara una constante llamada Const4 :

unit BConsts; interface const Const4 = 50; implementation end.

Ahora definimos una matriz en UnitA como esta:

unit AUnit interface uses BConsts; var data: array[0..Pred(Const4)] of Integer; implementation uses AConsts; procedure Work; var i: Integer; begin for i := 0 to Const4 - 1 do begin data[i] := 8; end; end; end.

Ese código escribirá más allá del final de la matriz porque el Const4 que está en el alcance en la sección de interfaz no es el mismo Const4 que se utiliza en la sección de implementación. Esto no sucede a menudo con constantes. Suele suceder con dos identificadores, la función FindClose definida en Windows y SysUtils , y TBitmap , definida en Graphics y Windows . Y en esos dos casos, el compilador le dirá que ha hecho algo mal, aunque no le dirá con precisión que ha usado un identificador que tiene dos significados diferentes. Puede resolver el problema calificando el identificador:

for i := 0 to BConsts.Const4 - 1 do data[i] := 8;

Si se abordan todas las precauciones anteriores, entonces su programa se compila y se ejecuta correctamente, entonces no importa dónde se usan las unidades. En su ejemplo con App1 y App2, los dos programas serán iguales. No serán idénticos, el compilador habrá procesado las cosas en un orden diferente y, por lo tanto, probablemente coloque las cosas en lugares diferentes, pero no tendrá ningún efecto en la ejecución de su programa.


Los elementos en la declaración de usos en la interfaz son visibles en toda la unidad.

Los elementos en la declaración de usos en la implementación solo son visibles en la sección de implementación.

Ejemplo:

unit A; interface const cA = 1; .. unit B; interface const cB = 1; .. unit C; interface uses A; const cC1 = cA; cC2 = cB; // Error implementation uses B; const cC3 = cA; cC4 = cB; end.

Puede crear unidades dependientes mutuas si se incluye al menos una unidad en la sección de implementación:

unit A; interface implementation uses B; end. unit B; interface implementation uses A; end.

Si ambos se usan en la sección de interfaz, no compilarán / vincularán.


Puse todas las referencias en la sección de implementación y solo pongo esos nombres de unidad en la interfaz que tengo que hacer.

Sin embargo, me gusta limitar el alcance de todo tanto como sea posible, y esta política se basa en eso.


Sigo una regla de que pongo todo en la parte Interfaz a menos que tenga que lidiar con problemas con las referencias circulares. Esto ayuda a traer un poco de claridad. Algunos asistentes en Delphi y el cuadro de diálogo "Archivo> Usar unidad ..." colocan unidades en la sección de implementación.

Excepto por las trampas de alcance que Rob Kennedy destacó, no importa. Haga su estándar y quédese con él.