Delphi TVector3D.AddVector3D不工作(对我而言)
使用Delphi XE4 update1和FMX,我想在滚轮鼠标事件中使用以下代码移动相机: AVector:=Vector3D0,0,3; Camera.Position.Vector.AddVector3DAVector; 代码编译时,什么也不做。使用反调试器,Camera.Position.Vector值不会更改 当使用 AVector:=Vector3D0,0,3; Camera.Position.Vector:=Camera.Position.Vector+AVector; …它起作用了!!!奇怪的是AddVector3D函数正好可以完成这段代码 程序TVector3D.AddVector3Dconst AVector3D:TVector3D; 开始 Self:=Self+3d; 终止 我的代码有什么问题?Camera.Position是TPosition3D类型。Vector是TVector3D类型的属性,带有getter和setter。请注意,TVector3D是一个记录,它是一种值类型而不是引用类型。这一细节至关重要 因此,当您编写Camera.Position.Vector时,您指的是该向量的副本。它是一个副本,因为TVector3D是一个值类型 因此,非工作代码相当于:Delphi TVector3D.AddVector3D不工作(对我而言),delphi,firemonkey,delphi-xe4,Delphi,Firemonkey,Delphi Xe4,使用Delphi XE4 update1和FMX,我想在滚轮鼠标事件中使用以下代码移动相机: AVector:=Vector3D0,0,3; Camera.Position.Vector.AddVector3DAVector; 代码编译时,什么也不做。使用反调试器,Camera.Position.Vector值不会更改 当使用 AVector:=Vector3D0,0,3; Camera.Position.Vector:=Camera.Position.Vector+AVector; …它起作用
var
TempVec: TVector3D;
....
TempVec := Camera.Position.Vector;
TempVec.AddVector3D(...);
显然,对AddVector3D的调用不会修改Camera.Position,因为对AddVector3D的调用只会改变临时本地设置
在代码中,该临时局部变量仍然存在,但您尚未为其命名。这是一个隐藏的隐式变量
为了修改位置,必须为Vector属性赋值,这正是工作代码所做的
一般来说,支持就地突变的值类型通常表示设计不佳。因此,在我看来,Embarcadero工程师不应该添加突变实例方法,如AddVector3D、Normalize、Scale等。这些方法导致了这种混乱。相反,使用返回新值的函数可以更好地实现该功能,就像重载运算符一样。Camera.Position是TPosition3D类型。Vector是TVector3D类型的属性,带有getter和setter。请注意,TVector3D是一个记录,它是一种值类型而不是引用类型。这一细节至关重要
因此,当您编写Camera.Position.Vector时,您指的是该向量的副本。它是一个副本,因为TVector3D是一个值类型
因此,非工作代码相当于:
var
TempVec: TVector3D;
....
TempVec := Camera.Position.Vector;
TempVec.AddVector3D(...);
显然,对AddVector3D的调用不会修改Camera.Position,因为对AddVector3D的调用只会改变临时本地设置
在代码中,该临时局部变量仍然存在,但您尚未为其命名。这是一个隐藏的隐式变量
为了修改位置,必须为Vector属性赋值,这正是工作代码所做的
一般来说,支持就地突变的值类型通常表示设计不佳。因此,在我看来,Embarcadero工程师不应该添加突变实例方法,如AddVector3D、Normalize、Scale等。这些方法导致了这种混乱。相反,使用返回新值的函数可以更好地实现该功能,就像重载运算符一样。@TridenT这有意义吗?看到Camera.Position.Vector返回向量的副本,我真的感到惊讶和难过。。。这是完美的大卫与您的答案总是:Thx的细节!还一份就可以了。从概念上讲,它与Integer类型的属性没有什么不同,比如,它也返回一个副本,因为Integer是一个值类型。不同之处在于TVector3D具有修改自身的实例方法。在我看来,这些变异实例方法的存在是导致混乱的原因。@TridenT这有意义吗?看到Camera.Position.Vector返回向量的副本,我真的感到惊讶和悲伤。。。这是完美的大卫与您的答案总是:Thx的细节!还一份就可以了。从概念上讲,它与Integer类型的属性没有什么不同,比如,它也返回一个副本,因为Integer是一个值类型。不同之处在于TVector3D具有修改自身的实例方法。在我看来,这些变异实例方法的存在是导致混乱的原因。