delphi – 作为Record的属性的DWScript setter

我的问题非常简单.

我有一个dwsUnit,它有这个代码:

type
  TPointCoord = record
    X: Float;
    Y: Float;
    Z: Float;
  end;

type
  TMyClass = class
  private
    fPosition: TPointCoord;

    function GetPosition: TPointCoord;
    procedure SetPosition(Val: TPointCoord);
  public
    property Position: TPointCoord read GetPosition write SetPosition;
    constructor Create;
end;

function TMyClass.GetPosition: TPointCoord;
begin
  Result := fPosition;
end;

procedure TMyClass.SetPosition(Val: TPointCoord);
begin
  fPosition := Val;
end;

constructor TMyClass.Create;
begin
  inherited Create;
  fPosition.X := 1;
  fPosition.Y := 2;  
  fPosition.Z := 3;    
end;

var
  mc: TMyClass;
begin
  mc := TMyClass.Create;
  mc.Position.X := 2;   //Syntax Error
end.

在mc.Position.X(或Position.Y或Z)我得到:

Syntax Error: Cannot assign a value to the left-side argument [line: 42, column: 17]

这是什么意思?如果是属性,记录是只读的吗?
我如何从Delphi Side访问它. (第二个问题,不是很重要)

最佳答案 出现此错误的原因是因为您使用的是属性为record的属性.

记录类型是一种值类型,这意味着它在赋值时被复制而不是被引用(如类),因此返回记录的函数(或属性)将生成一个副本并返回不同的记录.

所以你的路线

mc.Position.X := 2

实际上相当于

temp := mc.getPosition;
temp.X := 2;

“temp”是与fPosition不同的变量/存储,因此代码不会改变fPosition.X,它只会是“隐藏”临时副本的X字段.

由于这通常不太可能是您所追求的,DWS编译器就像Delphi一样,会抛出错误.

典型的解决方案是提供一个独特的PositionX属性,它将提供对fPosition的X字段的访问

property PositionX : TPointCoord read (FPosition.X) write (FPosition.X);

或者你可以使用显式的getter / setter,如果你需要超过分配的X字段.

另一种解决方案是使用引用类型(类f.i.),尽管这对于位置或坐标可能不太实用.

点赞