Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi TVector3D.AddVector3D不工作(对我而言)_Delphi_Firemonkey_Delphi Xe4 - Fatal编程技术网

Delphi TVector3D.AddVector3D不工作(对我而言)

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; …它起作用

使用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是一个值类型

因此,非工作代码相当于:

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具有修改自身的实例方法。在我看来,这些变异实例方法的存在是导致混乱的原因。