有没有更简单的方法进行布尔类型转换?

21

在我的几乎所有项目中,我经常使用这种场景,当我正在进行某种数据转换时,当涉及布尔值时,我会有点迷失,不知道如何简化。下面这个语句在我的代码中到处都是,非常突兀:

if BoolVal then
  StrVal:= 'True'
else
  StrVal:= 'False';

我想知道有没有更简单的方法进行这个评估?也许可以使用Case语句,但我不确定是否可行。我的实际实现比StrVal复杂,但根据True或False返回两个不同的值。下面是一些真实代码的例子...

if fsBold in Can.Font.Style then
  ConvertTo(AddSomeOtherText + 'True')
else
  ConvertTo(AddSomeOtherText + 'False');

那只是为了强调我希望的简单。我在想是否可以做类似于这样的事情:

ConvertTo(AddSomeOtherText + BoolToStrCase((fsBold in Can.Font.Style), 'True', 'False'));

我确定那不是一个真正的命令,但我正在寻找一行代码中的简单操作。


好的,那并不是真正的“实际”代码,只是一个例子,说明我讨厌为每个布尔值评估重复编写代码。 - Jerry Dodge
你的编程语言是否支持三元运算符?StrVal =: BoolVal ? 'True' : 'False' - vgoff
奇怪的是,我发现StackOverflow上关于Delphi的前一个问题也在问如何使布尔比较简单。完全不同的问题,有不同的答案,但两个问题都挨在一起... - Jerry Dodge
5个回答

45

在单元StrUtils中,有一个ifthen()函数。

StrVal := IfThen(BoolVal,'True','False');

而对于这个特定情况,您甚至可以使用:

StrVal := BoolToStr(BoolVal);

在我的 Delphi 版本(XE4)中,BoolToStr 已经移动到 SysUtils。 - DamienD
9
使用BoolToStr()函数时要小心。当其参数UseBoolStrs为false(默认情况下),输出是'-1''0';而当UseBoolStrs为true时,输出基于TrueBoolStrsFalseBoolStrs数组,因此在所有系统上您可能并不总是能获得'True''False'。如果您需要可预测的结果,可以考虑使用IfThen()函数。 - Remy Lebeau

25

咦,怎么没人听说过通过布尔值作为数组索引的方法吗?

const
  BOOL_TEXT: array[boolean] of string = ('False', 'True');
  YES_NO_TEXT: array[boolean] of string = ('No', 'Yes');
  ERROR_OR_WARNING_TEXT: array[boolean] of string = ('Warning', 'Error');

这实际上就是 BoolToStr 本身使用的方法!

function BoolToStr(B: Boolean; UseBoolStrs: Boolean = False): string;
const
  cSimpleBoolStrs: array [boolean] of String = ('0', '-1');

6
@UliGerhardt: 啊,是的,我也觉得它很丑,但在阅读代码时有助于识别常量,所以我很乐意忍受这份丑陋。;-) - Marjan Venema
4
始终将常量大写是标准的代码格式规则。 - Jerry Dodge

7

要将布尔值转换为字符串,可以使用BoolToStr函数,自Delphi 2007以来就一直存在。您可以在最后一个示例中如下使用它:

TextVal := BoolToStr((fsBold in Can.Font.Style), True);

如果要将字符串转换为布尔值,您需要编写一个实际的函数。以下代码可以帮助您入门:

function StringToBoolean(const Value: string): Boolean;
var
  TempStr: string;
begin
  TempStr := UpperCase(Value);
  Result := (TempStr = 'T') or 
            (TempStr = `TRUE`) or 
            (TempStr = 'Y');
end;

BoolVal := StringToBoolean('True');     // True
BoolVal := StringToBoolean('False');    // False
BoolVal := StringToBoolean('tRuE');     // True

当然,如果Value中有无意义的内容,这种方法就不起作用了...

谢谢,但是Wouter的答案完美地填补了我问题中的空缺过程,我的“BoolToStrCase”实际上就是“IfThen”。 - Jerry Dodge
另外编辑了一次,但是SO不让我提交... 我已经构建好了这个程序,并且支持整数0/1或0/>0或0/<>0等。 - Jerry Dodge
@KenWhite 是 TempStr 只是为了练手吗?;o) - 好的,现在有意义了 :o) - Sir Rufo
这是D2007 - 这是我目前正在使用的! - Gerry Coll
TrueBoolStrs/FalseBoolStrs 在 D2006 中就已经存在了,甚至可能更早。 - Marjan Venema
显示剩余5条评论

3
尝试使用以下任一选项。它们都比默认版本快得多。
type
 TBooleanWordType = (bwTrue, bwYes, bwOn, bwEnabled, bwSuccessful, bwOK, bwBinary);

 BooleanWord: array [Boolean, TBooleanWordType] of String =
  (
    ('False', 'No',  'Off', 'Disabled', 'Failed',     'Cancel', '0'),
    ('True',  'Yes', 'On',  'Enabled',  'Successful', 'Ok',     '1')
  );

function BoolToStr(Value: boolean; const BooleanWordType: TBooleanWordType = bwTrue): String; inline;
begin
   Result := BooleanWord[Value, BooleanWordType];
end;

function StrToBool(const S: String): Boolean; inline;
begin
  Result := False;
  case Length(S) of
    4: Result := (LowerCase(S) = 'true');
    5: Result := not (LowerCase(S) = 'false');
  end;
end;

1
这将把一个字符串转换为布尔值,但我要做相反的工作,即布尔值转换为字符串。 - Jerry Dodge
@JerryDodge 哦,让我修改我的答案 :) 我也有一个解决方案。 - Eric Santos
这里已经有比我需要的更多的答案了,我很难相信还有另一种解决方案。 - Jerry Dodge
@JerryDodge 是的,有一种方式更加灵活;) - Eric Santos
目前 StrToBool() 函数的方式,您可以删除整个 5 case。 当您提供 'false' 时,它会将结果设置为 false,但默认情况下已经是 false。 另外,当你调用 StrToBool('xxxxx') 时,它将返回 true,而 'xxxx' 或 'xxxxxx' 将返回 false。我认为这里使用这样的代码会更好: function StrToBool(const s:string):boolean; var b:TBooleanType; begin for b:=low(TbooleanWordType) to high(TbooleanWordType) do if SameText(BooleanWord[true,b],s) then Exit(True); Exit(False) end; - Wouter van Nifterick
这个答案帮助我解决了一个完全不同的问题。 - Nasreddine Galfout

3
如果你喜欢晦涩难懂的代码,这里有一种有趣的方法来实现它(特别是当它是更大的格式化语句的一部分时),但是如果你有更多的参数跟在后面(或前面),你将不得不显式地索引跟在布尔值之后的参数(我告诉过你这很晦涩)。格式如下:Format('The value of value is %*:s', [Integer(value)+1, 'False', 'True']);。任何在生产代码中使用此方法的人都应该受到严厉的惩罚!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接