如何初始化布尔类型以供局部变量使用?
How to initialize Boolean type to be used by local variables?
我正在尝试更改我使用布尔参数的方式以获得有意义的名称,因此我不需要检查每个方法 True/False 的含义。在这个例子中我使用 True/False:
procedure ProcessData(Param1, Param2: string; CreateOnEmpty: boolean = False);
procedure TForm1.Button1Click(Sender: TObject);
begin
ProcessData(P1, P2, True); // when CreateOnEmpty should be True
ProcessData(P1, P2); // when CreateOnEmpty should be False
ProcessData(P1, P2, False); // when CreateOnEmpty should be False
end;
但在这种情况下,我需要查找 ProcessData 方法以查看 True/False 参数的含义,执行。
所以,我从这个例子开始,为参数分配有意义的名称:
procedure TForm1.Button2Click(Sender: TObject);
var
vCreateWhenEmpty: boolean;
vDontCreateWhenEmpty: boolean;
begin
// Init control params
vCreateWhenEmpty := True;
vDontCreateWhenEmpty := False;
ProcessData(P1, P2, vCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, vDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
但是,我想避免初始化局部变量并且正在考虑这样的事情:
procedure TForm1.Button3Click(Sender: TObject);
Type
TBoolTrue = Boolean = True; // Init to True and all local vars will be True
TBoolFalse = Boolean = False; // Init to False and all local vars will be False
var
vCreateWhenEmpty: TBoolTrue; // Variable should default to True
vDontCreateWhenEmpty: TBoolFalse; // Variable should default to False
begin
ProcessData(P1, P2, vCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, vDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
所以,我可以跳过赋值 True/False。
我有 100 多个接受布尔参数的方法,所以 100 多个我可以用作参数的常量或全局变量听起来有点过分了。
是否有可能以某种方式将布尔类型初始化为 True/False 或避免使用其他技巧初始化局部变量?
编辑:
我在示例中将布尔类型设置为局部类型,我打算将它们设置为全局类型,因此它们只设置一次,而不是每次都在每个方法中设置。
所以,这将是全局的而不是本地的:
Type
TBoolTrue = Boolean = True; // Init to True and all local vars will be True
TBoolFalse = Boolean = False; // Init to False and all local vars will be False
编辑 2:
我希望问题不会结束,因为答案中有一些很好的建议。所以我的选择是:
全局常量(我最终会得到 100 个新常量)
全局枚举字段(即使我最终会得到 100 个,与 const 一样,如果我添加第三个值,它们允许更容易扩展值)
- 本地常量(我喜欢这个,因为它很短,每个常量 1 行,而且它是本地的,而不是全局的)
- 局部变量(每个变量 2 行,定义和值初始化 - 太多)
- 本地枚举字段(我喜欢这个,因为它可以用第三个或第四个值扩展...)
- Rufo 爵士的带有自动初始化记录的示例(虽然有点过头,但正是我想要的;不幸的是,一个真正过头的实现;性能可能会受到影响,但解决方案可用 - 很好)
- 保持原样,依靠代码洞察力来快速理解参数——不幸的是,在 XE7 中不稳定,不能依赖;也许新版本更好,但从对新版本的反馈来看,我怀疑它是否会按预期工作。
决定
尽管 Rufo 爵士关于如何做我想做的事情的技巧是独一无二的,但我意识到我正在努力实现当前 Delphi 版本所不具备的东西。因此,我将结合使用常量和枚举类型,只在真正需要的地方应用,而不是在所有地方应用,并且会避免使用 100 多个全局变量和局部变量。
无法自动初始化局部变量。您必须在代码中这样做,或者(尽管不想)使用 const
而不是类型,声明在与将使用它们的函数相同的范围内。
const
vCreateWhenEmpty = True;
vDontCreateWnenEmpty = False;
procedure ProcessData(Param1, Param2: string; CreateOnEmpty: boolean = False);
之后:
ProcessData(P1, P2, vCreateWhenEmpty);
ProcessData(P1, P2, vDontCreateWhenEmpty);
我个人会将布尔变量替换为具有公共前缀的枚举类型。
type
TProcessDataCreateOpt = (coCreate, coSkip);
procedure ProcessData(Param1, Param2: string; CreateOpt: TProcessDataCreateOpt = coSkip);
这使其更具可读性,Code Insight 和 Code Completion 可以帮助您获得正确的值,并且您根本不需要任何局部或全局变量。
我认为你应该保持原样。如果您想查看参数的名称是什么,您可以简单地使用代码洞察力来实现。
如果您还没有使用这些,那么您应该开始使用它们,让您的生活更轻松:
- Ctrl + Shift + 空格键调用代码参数提示 Delphi 5 及以上
- Ctrl + Shift + 向上箭头导航到方法 implementation/declaration
Delphi 5 岁及以上
- Ctrl + 单击转到声明。
无法自动初始化局部变量。
但是我们可以创建一个记录,其行为类似于自动初始化的局部变量。
type
TBoolDefaultTrue = record
private const
InitializedFlag = '*';
DefaultValue = True;
private
FIsInitialized: string;
FValue: Boolean;
procedure EnsureInitialized;
public
class operator implicit ( const v: Boolean ): TBoolDefaultTrue;
class operator implicit ( const v: TBoolDefaultTrue ): Boolean;
end;
procedure EnsureInitialized;
begin
if FIsInitialized = ''
then
begin
FValue := DefaultValue;
FIsInitialized := InitializedFlag;
end;
end;
class operator TBoolDefaultTrue.Implicit( const v: Boolean ): TBoolDefaultTrue;
begin
Result.FValue := v;
Result.FIsInitialized := InitializedFlag;
end;
class operator TBoolDefaultTrue.Implicit( const v: TBoolDefaultTrue ): Boolean;
begin
v.EnsureInitialized;
Result := v.FValue;
end;
并且您可以在不更改方法签名的情况下使用它
procedure TForm1.Button3Click(Sender: TObject);
var
vCreateWhenEmpty: TBoolDefaultTrue;
vDontCreateWhenEmpty: TBoolDefaultFalse;
begin
ProcessData(P1, P2, vCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, vDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
这只是您可以选择的一个选项,但对我而言,这不是我想要的选项。我喜欢肯在他的回答中描述的枚举方式。我只会选择不同的名字。
TProcessDataOption = ( pdoDontCreateWhenEmpty, pdoCreateWhenEmpty );
但这只是糖
正如其他人所说,目前没有办法初始化局部变量,但真正的问题是为什么它应该是变量。我从你的代码中了解到,在代码中初始化这些变量后,它们将永远不会改变它们的值。此外,该方法不会将这些参数声明为变量。在这种情况下,也可以通过局部常量来完成(只是为了避免全局常量)。因此,与其在代码中声明局部变量并初始化它们,不如声明局部常量。
procedure TForm1.Button3Click(Sender: TObject);
const
cCreateWhenEmpty = True;
cDontCreateWhenEmpty = False;
begin
ProcessData(P1, P2, cCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, cDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
关于长 运行 我还建议将声明的枚举类型用作参数,但如果您无法更改声明,上述解决方案应该完全符合您问题中提到的要求嗯
除了其他人已经建议的之外,如果您可以更改 ProcessData 方法的实现,您可以使用枚举而不是布尔值:
type
TCreateDisposition = (cdDontCreate, cdCreateIfEmpty);
procedure ProcessData(Param1, Param2: string; CreateDisposition: TCreateDisposition);
我正在尝试更改我使用布尔参数的方式以获得有意义的名称,因此我不需要检查每个方法 True/False 的含义。在这个例子中我使用 True/False:
procedure ProcessData(Param1, Param2: string; CreateOnEmpty: boolean = False);
procedure TForm1.Button1Click(Sender: TObject);
begin
ProcessData(P1, P2, True); // when CreateOnEmpty should be True
ProcessData(P1, P2); // when CreateOnEmpty should be False
ProcessData(P1, P2, False); // when CreateOnEmpty should be False
end;
但在这种情况下,我需要查找 ProcessData 方法以查看 True/False 参数的含义,执行。
所以,我从这个例子开始,为参数分配有意义的名称:
procedure TForm1.Button2Click(Sender: TObject);
var
vCreateWhenEmpty: boolean;
vDontCreateWhenEmpty: boolean;
begin
// Init control params
vCreateWhenEmpty := True;
vDontCreateWhenEmpty := False;
ProcessData(P1, P2, vCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, vDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
但是,我想避免初始化局部变量并且正在考虑这样的事情:
procedure TForm1.Button3Click(Sender: TObject);
Type
TBoolTrue = Boolean = True; // Init to True and all local vars will be True
TBoolFalse = Boolean = False; // Init to False and all local vars will be False
var
vCreateWhenEmpty: TBoolTrue; // Variable should default to True
vDontCreateWhenEmpty: TBoolFalse; // Variable should default to False
begin
ProcessData(P1, P2, vCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, vDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
所以,我可以跳过赋值 True/False。
我有 100 多个接受布尔参数的方法,所以 100 多个我可以用作参数的常量或全局变量听起来有点过分了。
是否有可能以某种方式将布尔类型初始化为 True/False 或避免使用其他技巧初始化局部变量?
编辑:
我在示例中将布尔类型设置为局部类型,我打算将它们设置为全局类型,因此它们只设置一次,而不是每次都在每个方法中设置。 所以,这将是全局的而不是本地的:
Type
TBoolTrue = Boolean = True; // Init to True and all local vars will be True
TBoolFalse = Boolean = False; // Init to False and all local vars will be False
编辑 2:
我希望问题不会结束,因为答案中有一些很好的建议。所以我的选择是:
全局常量(我最终会得到 100 个新常量)
全局枚举字段(即使我最终会得到 100 个,与 const 一样,如果我添加第三个值,它们允许更容易扩展值)
- 本地常量(我喜欢这个,因为它很短,每个常量 1 行,而且它是本地的,而不是全局的)
- 局部变量(每个变量 2 行,定义和值初始化 - 太多)
- 本地枚举字段(我喜欢这个,因为它可以用第三个或第四个值扩展...)
- Rufo 爵士的带有自动初始化记录的示例(虽然有点过头,但正是我想要的;不幸的是,一个真正过头的实现;性能可能会受到影响,但解决方案可用 - 很好)
- 保持原样,依靠代码洞察力来快速理解参数——不幸的是,在 XE7 中不稳定,不能依赖;也许新版本更好,但从对新版本的反馈来看,我怀疑它是否会按预期工作。
决定
尽管 Rufo 爵士关于如何做我想做的事情的技巧是独一无二的,但我意识到我正在努力实现当前 Delphi 版本所不具备的东西。因此,我将结合使用常量和枚举类型,只在真正需要的地方应用,而不是在所有地方应用,并且会避免使用 100 多个全局变量和局部变量。
无法自动初始化局部变量。您必须在代码中这样做,或者(尽管不想)使用 const
而不是类型,声明在与将使用它们的函数相同的范围内。
const
vCreateWhenEmpty = True;
vDontCreateWnenEmpty = False;
procedure ProcessData(Param1, Param2: string; CreateOnEmpty: boolean = False);
之后:
ProcessData(P1, P2, vCreateWhenEmpty);
ProcessData(P1, P2, vDontCreateWhenEmpty);
我个人会将布尔变量替换为具有公共前缀的枚举类型。
type
TProcessDataCreateOpt = (coCreate, coSkip);
procedure ProcessData(Param1, Param2: string; CreateOpt: TProcessDataCreateOpt = coSkip);
这使其更具可读性,Code Insight 和 Code Completion 可以帮助您获得正确的值,并且您根本不需要任何局部或全局变量。
我认为你应该保持原样。如果您想查看参数的名称是什么,您可以简单地使用代码洞察力来实现。
如果您还没有使用这些,那么您应该开始使用它们,让您的生活更轻松:
- Ctrl + Shift + 空格键调用代码参数提示 Delphi 5 及以上
- Ctrl + Shift + 向上箭头导航到方法 implementation/declaration Delphi 5 岁及以上
- Ctrl + 单击转到声明。
无法自动初始化局部变量。
但是我们可以创建一个记录,其行为类似于自动初始化的局部变量。
type
TBoolDefaultTrue = record
private const
InitializedFlag = '*';
DefaultValue = True;
private
FIsInitialized: string;
FValue: Boolean;
procedure EnsureInitialized;
public
class operator implicit ( const v: Boolean ): TBoolDefaultTrue;
class operator implicit ( const v: TBoolDefaultTrue ): Boolean;
end;
procedure EnsureInitialized;
begin
if FIsInitialized = ''
then
begin
FValue := DefaultValue;
FIsInitialized := InitializedFlag;
end;
end;
class operator TBoolDefaultTrue.Implicit( const v: Boolean ): TBoolDefaultTrue;
begin
Result.FValue := v;
Result.FIsInitialized := InitializedFlag;
end;
class operator TBoolDefaultTrue.Implicit( const v: TBoolDefaultTrue ): Boolean;
begin
v.EnsureInitialized;
Result := v.FValue;
end;
并且您可以在不更改方法签名的情况下使用它
procedure TForm1.Button3Click(Sender: TObject);
var
vCreateWhenEmpty: TBoolDefaultTrue;
vDontCreateWhenEmpty: TBoolDefaultFalse;
begin
ProcessData(P1, P2, vCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, vDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
这只是您可以选择的一个选项,但对我而言,这不是我想要的选项。我喜欢肯在他的回答中描述的枚举方式。我只会选择不同的名字。
TProcessDataOption = ( pdoDontCreateWhenEmpty, pdoCreateWhenEmpty );
但这只是糖
正如其他人所说,目前没有办法初始化局部变量,但真正的问题是为什么它应该是变量。我从你的代码中了解到,在代码中初始化这些变量后,它们将永远不会改变它们的值。此外,该方法不会将这些参数声明为变量。在这种情况下,也可以通过局部常量来完成(只是为了避免全局常量)。因此,与其在代码中声明局部变量并初始化它们,不如声明局部常量。
procedure TForm1.Button3Click(Sender: TObject);
const
cCreateWhenEmpty = True;
cDontCreateWhenEmpty = False;
begin
ProcessData(P1, P2, cCreateWhenEmpty); // When CreateOnEmpty should be True
ProcessData(P1, P2, cDontCreateWhenEmpty); // When CreateOnEmpty should be False
end;
关于长 运行 我还建议将声明的枚举类型用作参数,但如果您无法更改声明,上述解决方案应该完全符合您问题中提到的要求嗯
除了其他人已经建议的之外,如果您可以更改 ProcessData 方法的实现,您可以使用枚举而不是布尔值:
type
TCreateDisposition = (cdDontCreate, cdCreateIfEmpty);
procedure ProcessData(Param1, Param2: string; CreateDisposition: TCreateDisposition);