Delphi 德尔福2010+;及;无法将左侧指定给“左”;在只读记录中:是否可以禁用此功能?
我知道。我知道为什么。但是Delphi 德尔福2010+;及;无法将左侧指定给“左”;在只读记录中:是否可以禁用此功能?,delphi,delphi-2010,Delphi,Delphi 2010,我知道。我知道为什么。但是 TComplicatedCallMaker = record Param1: TRecordType; Param2: TRecordType; {...} Param15: TRecordType; procedure Call; end; function ComplicatedCall: TComplicatedCallMaker; begin { Fill default param values } end; p
TComplicatedCallMaker = record
Param1: TRecordType;
Param2: TRecordType;
{...}
Param15: TRecordType;
procedure Call;
end;
function ComplicatedCall: TComplicatedCallMaker;
begin
{ Fill default param values }
end;
procedure DoingSomeWorkHere;
begin
with ComplicatedCall do begin
Param7 := Value7;
Param12 := Value12;
Call;
end;
end;
这在德尔福2010年之前已经非常有效了。这是一种非常有用的技术,用于进行接受大量参数但通常只需要两到三个参数的调用。但从来都不一样
现在它给。。。你猜怎么着
E2064: Left side cannot be assigned to.
难道不能以某种方式禁用这种有用的新行为吗?有没有关于如何修改模式使其工作的想法
因为说真的,没有明显的原因就失去了这么一种简便的技术(并重写了一堆代码)…我觉得这有点令人惊讶,但既然你这么说,我相信你是对的。我猜这个改变是在没有考虑记录方法的情况下做出的。如果没有调用方法的能力,那么这个构造将毫无意义 无论如何,编译器不会让你在这个问题上脱身,所以你必须这样做:
type
TRecordType = record end;
TComplicatedCallMaker = record
Param1: TRecordType;
procedure Call;
end;
function ComplicatedCall: TComplicatedCallMaker;
begin
{ Fill default param values }
end;
procedure DoingSomeWorkHere(const Value: TRecordType);
var
CallMaker: TComplicatedCallMaker;
begin
CallMaker := ComplicatedCall;
with CallMaker do begin
Param1 := Value;
Call;
end;
end;
我觉得这有点令人惊讶,但既然你说它起作用了,我相信你是对的。我猜这个改变是在没有考虑记录方法的情况下做出的。如果没有调用方法的能力,那么这个构造将毫无意义 无论如何,编译器不会让你在这个问题上脱身,所以你必须这样做:
type
TRecordType = record end;
TComplicatedCallMaker = record
Param1: TRecordType;
procedure Call;
end;
function ComplicatedCall: TComplicatedCallMaker;
begin
{ Fill default param values }
end;
procedure DoingSomeWorkHere(const Value: TRecordType);
var
CallMaker: TComplicatedCallMaker;
begin
CallMaker := ComplicatedCall;
with CallMaker do begin
Param1 := Value;
Call;
end;
end;
我我想是我干的
我希望Delphi开发人员看到他们让程序员做什么
type
PCallMaker = ^TCallMaker;
TCallMaker = record
Param1: integer;
Param2: integer;
function This: PCallMaker; inline;
procedure Call; inline;
end;
function TCallMaker.This: PCallMaker;
begin
Result := @Self;
{ Record functions HAVE to have correct self-pointer,
or they wouldn’t be able to modify data. }
end;
procedure TCallMaker.Call;
begin
writeln(Param1, ' ', Param2);
end;
function CallMaker: TCallMaker; inline
begin
Result.Param1 := 0;
Result.Param2 := 0;
end;
procedure DoingSomeWorkHere;
var cm: TCallMaker;
begin
{Test the assumption that cm is consistent}
cm := CallMaker;
if cm.This <> @cm then
raise Exception.Create('This wasn''t our lucky day.');
{Make a call}
with CallMaker.This^ do begin
Param1 := 100;
Param2 := 500;
Call;
end;
end;
类型
PCallMaker=^TCallMaker;
TCallMaker=记录
Param1:整数;
参数2:整数;
功能:PCallMaker;内联;
程序调用;内联;
结束;
函数TCallMaker.This:PCallMaker;
开始
结果:=@Self;
{记录函数必须具有正确的自指针,
否则他们将无法修改数据。}
结束;
过程TCallMaker.Call;
开始
writeln(Param1',Param2);
结束;
函数调用器:TCallMaker;内联
开始
Result.Param1:=0;
Result.Param2:=0;
结束;
在这里做一些工作的程序;
var-cm:TCallMaker;
开始
{测试cm一致性的假设}
cm:=呼叫者;
如果cm.这个@cm那么
引发异常。创建('这不是我们的幸运日');
{打电话}
使用CallMaker。此^do开始
参数1:=100;
参数2:=500;
呼叫
结束;
结束;
这种方法有效,保留了旧版本的所有优点(速度快、简单、调用开销小),但这种方法是否存在任何隐藏的问题?I。。。我想是我干的
我希望Delphi开发人员看到他们让程序员做什么
type
PCallMaker = ^TCallMaker;
TCallMaker = record
Param1: integer;
Param2: integer;
function This: PCallMaker; inline;
procedure Call; inline;
end;
function TCallMaker.This: PCallMaker;
begin
Result := @Self;
{ Record functions HAVE to have correct self-pointer,
or they wouldn’t be able to modify data. }
end;
procedure TCallMaker.Call;
begin
writeln(Param1, ' ', Param2);
end;
function CallMaker: TCallMaker; inline
begin
Result.Param1 := 0;
Result.Param2 := 0;
end;
procedure DoingSomeWorkHere;
var cm: TCallMaker;
begin
{Test the assumption that cm is consistent}
cm := CallMaker;
if cm.This <> @cm then
raise Exception.Create('This wasn''t our lucky day.');
{Make a call}
with CallMaker.This^ do begin
Param1 := 100;
Param2 := 500;
Call;
end;
end;
类型
PCallMaker=^TCallMaker;
TCallMaker=记录
Param1:整数;
参数2:整数;
功能:PCallMaker;内联;
程序调用;内联;
结束;
函数TCallMaker.This:PCallMaker;
开始
结果:=@Self;
{记录函数必须具有正确的自指针,
否则他们将无法修改数据。}
结束;
过程TCallMaker.Call;
开始
writeln(Param1',Param2);
结束;
函数调用器:TCallMaker;内联
开始
Result.Param1:=0;
Result.Param2:=0;
结束;
在这里做一些工作的程序;
var-cm:TCallMaker;
开始
{测试cm一致性的假设}
cm:=呼叫者;
如果cm.这个@cm那么
引发异常。创建('这不是我们的幸运日');
{打电话}
使用CallMaker。此^do开始
参数1:=100;
参数2:=500;
呼叫
结束;
结束;
这种方法有效,保留了旧版本的所有优点(速度快、简单、调用开销小),但这种方法是否存在任何隐藏的问题?可能与以前的方法重复,我很惊讶这种方法曾经奏效。@David Hefferman:为什么?这是一个非常有效的伎俩。没有黑客攻击,只有语言功能。它被删除了,因为它本来就不应该被允许。我无法将这个问题与参考文献进行比较。特别是因为属性总是按照主题描述的方式运行,所以它从未“改变”。我很惊讶它可能会重复使用。@David Hefferman:为什么?这是一个非常有效的伎俩。没有黑客攻击,只有语言功能。它被删除了,因为它本来就不应该被允许。我无法将这个问题与参考文献进行比较。特别是因为属性总是按照主题所描述的方式运行,所以它从未“改变”。是的,我也直接尝试了,而且效果很好。但是这会杀死一半的美女。。。真的没有其他方法吗?你可以使用一个类的实例,但是你必须释放它是的,而且它比返回记录(可能是堆栈分配的!)慢得多。这里没有什么好杀的。这完全是一种丑陋的黑客行为,以前依靠的是一个坏掉的编译器。编译器现在已经修好了。@Warren P:不,不是。黑客攻击是针对编译器的。这个技巧依赖于记录在案的预期行为。你想说什么就说什么,尽管这种用法对编译器开发人员来说是出乎意料的,但它是合法的。意外使用!=黑客。事实上,试图把你能做的限制在那些明确表示你能做的事情上是在扼杀这种本来就很丰富的语言。是的,我也直接尝试过了,而且奏效了。但是这会杀死一半的美女。。。真的没有其他方法吗?你可以使用一个类的实例,但是你必须释放它是的,而且它比返回记录(可能是堆栈分配的!)慢得多。这里没有什么好杀的。这完全是一种丑陋的黑客行为,以前依靠的是一个坏掉的编译器。编译器现在已经修好了。@Warren P:不,不是。黑客攻击是针对编译器的。这个技巧依赖于记录在案的预期行为。你想说什么就说什么,尽管这种用法对编译器开发人员来说是出乎意料的,但它是合法的。意外使用!=黑客。事实上,试图将你能做的事情限制在明确说明你能做的事情上是在扼杀其他丰富的语言。有了这个解决方案,你无论如何都必须改变CallMaker的所有用法。所以我建议你一直使用一个显式变量,比如@David。您不会注意到任何开销,也不会因为中的而消除歧义