2010-04-30 10 views

Respuesta

9
A := List[10]; 
A.a := 1; 
list[10] := A; 

Usted no tiene que hacer esto con objetos porque son los tipos de referencia, (los que se accede a través de un puntero, que el compilador administra en su interior para mantenerlo fuera de su pelo,) pero los registros son de valor tipos por lo que no funciona de esa manera.

+0

es una manera simple y fuerte. pero cuando el tamaño del registro es muy grande, la pila se desborda debido a la variable local A y si esto funciona en un bucle o bucles es muy lento. –

6

Ha encontrado un inconveniente con el uso de registros.

consideran este código:

function Test: TTest; 
begin 
    ... 
end; 

Test.a := 1; 

Lo que su código es similar al compilador en realidad es la siguiente:

TTest temp := Test; 
temp.a := 1; 

El compilador le está diciendo, con el mensaje de error, que la asignación es inútil , ya que solo asignará un nuevo valor a un valor de registro temporal, que se olvidará instantáneamente.

Además, el @List[10] no es válido porque List[10] nuevamente solo devuelve un valor de registro temporal, por lo que tomar la dirección de ese registro es bastante inútil.

Sin embargo, leer y escribir todo el registro está bien.

Entonces, para resumir:

List[10] := A; <- writing a whole record is OK 
List[10].a:=1; <- List[10] returns a temporary record, pointless assignment 
P:[email protected][10]; <- List[10] returns a temporary record, its address is pointless 
+2

Sin embargo, los elementos de la propiedad son de lectura y escritura, y creo que Delphi podría entender que Items [1] .a: = 123 meens Items [1]: = TType (123, oldval2, oldval3) – Astronavigator

+0

Pero no ... La parte importante no es lo que el compilador * podría * hacer, sino lo que * realmente hace *. –

+1

@Astronavigator: Sí, la propiedad es R/W, pero no está accediendo directamente al campo. Simplemente devuelve una copia del campo. Verifique la respuesta de Mason para evitar esto. –

2

Si desea almacenar los registros, matrices dinámicas son más adecuadas para el manejo de ellos:

type TTest = record a,b,c : Integer end; 
type TTestList = array of TTest; 
var List:TTestList; 
    A:TTest; 
    P:Pointer; 
.... 
.... 

SetLength(List, 20); 
List[10] := A; //<- OK 
List[10].a := 1; //<- Ok 
P := @List[10]; //<- Not advised (the next SetLength(List,xx) will blow the address away), 
       // but technically works 

Si es necesario agregar métodos para manipular estos datos, puede almacenar esta matriz como el campo de una clase y agregar sus métodos a esta clase.

1

Si necesita manipular objetos en esa forma, es mejor utilizar TObjectList en lugar de TList, y definir la estructura como una clase en lugar de un registro:

type TTest = class a,b,c:Integer end; 
var List:TObjectList<TTest>; 
    A:TTest; // A is an object so there's no need for a pointer 
.... 
.... 
List.Add(TTest.Create); 
List.Last.a := 1; 
A:=List.Last; 
Cuestiones relacionadas