gpt4 book ai didi

delphi - 为什么在明显的 "safe"代码中使用异常处理?

转载 作者:行者123 更新时间:2023-12-03 14:55:02 25 4
gpt4 key购买 nike

请有人解释一下,这段代码中什么会引发异常?

function CreateBibleNames: TStrings;
begin
Result := TStringList.Create;
try
Result.Add('Adam');
Result.Add('Eva');
Result.Add('Kain');
Result.Add('Abel');
except
Result.Free;
raise;
end;
end;

自从我使用delphi以来,我可能使用过一次异常处理。我认为上面的代码是由熟练的程序员编写的,并且我不认为异常是多余的。但是,在这个概念中使用异常处理对我来说仍然是一个谜。这似乎是一个安全的代码(除了结束之外没有尝试)。我已经看过很多次类似的代码片段,这就是为什么尽管我的经验如此,但可能有充分的理由这样编写,但这并不能证明它是必要的。

此外,当出现故障时,我会收到异常描述......

谢谢

最佳答案

好吧,那段代码很奇怪,我同意,而且我完全理解为什么要这样写。但之所以这样写,是因为代码的前提是错误的。事实上,该结构看起来很奇怪,这应该是一种“代码味道”,并且应该告诉您某些事情可能没有以最佳方式完成。

首先,这就是为什么在 try... except block 中使用不寻常的构造。该函数创建一个 TStringList,但如果在填充过程中出现问题,那么创建的 TStringList 将在堆上“丢失”,并且会出现内存泄漏。因此,最初的程序员是防御性的,并确保如果发生异常,TStringList 将被释放,然后异常将再次引发。

现在这是“坏前提”部分。该函数返回 TStrings 的实例。这并不总是解决这个问题的最佳方法。返回这样的对象实例会引发一个问题“谁将处理我创建的这个东西?”。它造成了一种情况,在调用方,很容易忘记 TStrings 实例已被分配。

这里的“更好的实践”是让函数将 TStrings 作为参数,然后填充现有实例。这样,谁拥有实例(调用者)以及谁应该管理其生命周期就毫无疑问了。

因此,该函数成为一个过程,可能如下所示:

procedure CreateBibleNames(aStrings: TStrings);
begin
if aStrings <> nil then
begin
aStrings .Add('Adam');
aStrings .Add('Eva');
aStrings .Add('Kain');
aStrings .Add('Abel');
end;
end;

这并不是说每次返回对象实例都是一件坏事——例如,这是非常有用的工厂模式的唯一功能。但对于像这样的更“通用”的功能,上面是一种“更好”的做事方式。

关于delphi - 为什么在明显的 "safe"代码中使用异常处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1894983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com