即使我知道这永远不会发生,我仍然无法弄清楚如何在使用以下结构时摆脱有关未初始化变量的警告。
TCustomEnum = (ceValue1, ceValue2, ceValue3);
function DoSomething(LI_Enum: TCustomEnum): Integer;
var
lNumber : Integer;
begin
case LI_Enum of
ceValue1 : lNumber := 1;
ceValue2 : lNumber := 2;
ceValue3 : lNumber := 3;
end;
Result := 2 * lNumber;
end;
W1036变量“ lNumber”可能尚未初始化
我找到了3个解决方案,但我不喜欢其中任何一个。特别是带有更多变量或语句。还有其他方法可以避免这种情况吗?
使用
{$WARN USE_BEFORE_DEF OFF}
和{$WARN USE_BEFORE_DEF ON}
包装功能在每种情况下,在开头都使用
else Exit;
和Result := 0
初始化每个变量,尽管永远不会使用该值
最佳答案
我发现此编译器警告有些令人失望。毕竟,编译器肯定可以检测到您已经涵盖了枚举类型的所有可能值。我不认为您应该担心是否在枚举类型中输入了无效的序数,即使这确实是此警告背后的想法。
无论如何,我个人都使用以下辅助方法来解决此问题:
procedure RaiseAssertionFailed; overload;
procedure RaiseAssertionFailed(var v1); overload;
procedure RaiseAssertionFailed(var v1,v2); overload;
....
procedure DoRaiseAssertionFailed;
begin
raise EAssertionFailed.CreateFmt(
'A critical error has occurred:'+ sLineBreak + sLineBreak +
' Assertion failed at %p.'+ sLineBreak + sLineBreak +
'In order to avoid invalid results or data corruption please close the program and report '+
'the above error code along with any other information relating to this problem.',
[ReturnAddress]
) at ReturnAddress;
end;
procedure RaiseAssertionFailed;
asm
JMP DoRaiseAssertionFailed;
end;
procedure RaiseAssertionFailed(var v1);
asm
JMP DoRaiseAssertionFailed;
end;
procedure RaiseAssertionFailed(var v1,v2);
asm
JMP DoRaiseAssertionFailed;
end;
您的代码将变为:
function DoSomething(LI_Enum: TCustomEnum): Integer;
var
lNumber : Integer;
begin
case LI_Enum of
ceValue1 : lNumber := 1;
ceValue2 : lNumber := 2;
ceValue3 : lNumber := 3;
else
RaiseAssertionFailed(lNumber);
end;
Result := 2 * lNumber;
end;
这与@Dsm概述的方法非常相似。如果使用该方法,则编译器可以看到您正在引发异常,并且知道
lNumber
不需要初始化。我更喜欢将引发异常包装到共享函数中。这样,我不需要一次又一次地写相同的错误消息。 DRY原理的应用。
但是,如果执行此操作,然后将引发移到共享函数中,则编译器将无法确定该函数将引发异常。因此,无类型的var参数。这使您可以将变量标记为可能被修改,从而消除编译器警告。
还有一种方法是声明一个异常类,该异常类在其无参数构造函数中提供了文本。
type
EInternalError = class(Exception)
public
constructor Create;
end;
constructor EInternalError.Create;
begin
inherited Create(
'...' // your text goes here
);
end;
然后您的代码变为:
function DoSomething(LI_Enum: TCustomEnum): Integer;
var
lNumber : Integer;
begin
case LI_Enum of
ceValue1 : lNumber := 1;
ceValue2 : lNumber := 2;
ceValue3 : lNumber := 3;
else
raise EInternalError.Create;
end;
Result := 2 * lNumber;
end;
关于delphi - case语句中未初始化的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41737878/