我有以下功能
function calculate(s:string):integer;
begin
try
strtoint(s);
do_something;
except
result:=-1;
end;
end;
使用这样的例外会有什么后果吗?
答案 0 :(得分:7)
如果目的是检查输入字符串的有效性,那么有比异常处理程序更好的方法。要从字符串转换为整数并检测无效输入,请使用TryStrToInt
:
var
value: Integer;
...
if TryStrToInt(s, Value) then
Result := ...
else
Result := -1;
如果字符串可以转换为整数,则此函数返回True
,如果是,则通过第二个参数返回整数,out参数。否则该函数返回False
。在您的代码中,您忽略转换后的整数值,但如果需要,它可用。
在我看来,这比异常处理程序更受欢迎,因为它更加明确和简洁。更不用说避免引发和捕获异常的性能开销。
当然,您的代码将检测除无效字符串以外的其他故障。一个潜在的错误来源是您的do_something
程序。如果您真的想要吞下该过程引发的任何异常,则需要一个异常处理程序。但是,我更倾向于怀疑你的原始意图更有可能只捕获无效的字符串输入。在这种情况下,您的代码不正确。
另一个错误来源是s
恰好是无效的字符串变量。但如果发生这种情况,那么你的程序的整个基础都会从你的下方拉出来,我个人认为你不应该期望优雅地处理这些场景。
建议您的部分问题是您的代码可能不具有真正的代表性。例如,如果输入有效,它似乎不设置返回值。我们不确定您的异常处理程序的意图是什么。我猜你的意思是在对StrToInt
的调用中捕获错误,但我无法确定。
答案 1 :(得分:3)
这在很大程度上取决于Calculate
方法的规范。
如果规范规定在任何和所有例外情况下返回-1,那么这很好并且(格式化问题除外)可以简洁地完成工作可能的。
如果合同只是方法为无效(非数字)字符串返回-1,那么DoSomething
本身可能会引发其他异常(包括可能不相关的转换错误)的潜在问题错误处理,从Calculate
方法得到-1(使得无法区分 s 的无效值和其他错误。
在后一种情况下,以避免依赖异常的方式处理关于字符串参数的特定契约会更正确(因为在这种情况下错误不是"例外"但是要处理的特定输入案例),并允许调用者处理DoSomething
的异常(如果适用)。
要测试有效的数字字符串,您可以使用TryStrToInt
,只有在确定 s 是有效整数时才调用DoSomething
。假设Calculate
函数的结果对于无效输入为-1,对{strong> s 的数值进行DoSomething
运算的结果为:
function calculate(s: String):integer;
begin
if NOT TryStrToInt(s, result) then
result := -1;
else
result := DoSomething(result);
end;
以这种方式使用结果是个人喜好的问题。有些人认为你不应该像这样使用结果来处理存储空间,你应该使用一个单独的局部变量来保存 s 的整数值,并相应地命名:
function calculate(s: String): Integer;
var
inValue: Integer;
begin
if NOT TryStrToInt(s, inValue) then
result := -1;
else
result := DoSomething(inValue);
end;
FWIW:我个人赞成后者。 :)
答案 2 :(得分:1)
为什么不简单地选择这样的事情:
function calculate(s:string):integer;
begin
result:=-1;
strtoint(s);
do_something;
result:=.... <--- whatever value you want to return or maybe result:=do_something as Deltics shows
end;