我使用conditional operator COND
中的string template来创建字符串以连接变量Alpha和Beta。如果Alpha是初始的,则字符串是初始的,但如果不是,则结果应该是' Alpha'如果Beta是初始的,但是' Alpha-Beta'如果Beta不是首字母。
这是代码:
DATA:
lv_alpha TYPE string VALUE 'Alpha',
lv_beta TYPE string VALUE 'Beta',
lv_result TYPE string.
lv_result = COND #( WHEN lv_alpha IS INITIAL THEN '' ELSE
|{ lv_alpha }{ COND #( WHEN lv_beta IS INITIAL THEN '' ELSE |-{ lv_beta }| ) }|
).
现在的问题是,当我运行它时,lv_result实际上会返回:' Alpha - ',因此lv_beta
的值不包括在内,即使我知道代码输入了内部COND
语句的第二部分。 造成这种情况的原因是什么?
答案 0 :(得分:0)
当您使用#
作为operand type并且类型推断的结果与您想要的结果不符时,您会看到此行为。
如果你查看Type Inference for Actual Parameters上的文档,它会解释:
如果使用字符
COND|SWITCH #( ... THEN ... )
作为操作数类型的符号将构造函数表达式#
作为实际参数传递给一般类型的形式参数,则对字符{{执行以下类型推断1}}:
如果第一个THEN之后的操作数的数据类型是静态可识别的并且与形式参数的泛型类型匹配,则使用此数据类型。
如果第一个THEN之后的操作数的数据类型是静态可识别的,并且与形式参数的泛型类型不匹配,或者静态不可识别,则类型从泛型类型派生,如下所示:
您在内部#
而不是外部{1}}上看到这一点的事实是因为外部类型推断看起来是COND
的字符串类型。内部lv_result
没有要查看的直接类型,因此使用静态可识别类型COND
,默认为''
。
您可以通过运行以下命令轻松地观察此行为。每个的输出都在CHAR(1)
之后。
"
在两个第一个命令中,类型都是从DATA(lv_test) = 'ABCDEFG'.
WRITE :/ COND #( WHEN lv_alpha IS INITIAL THEN '' ELSE lv_test ). " A
WRITE :/ COND #( WHEN lv_alpha IS INITIAL THEN '123' ELSE lv_test ). " ABC
WRITE :/ COND string( WHEN lv_alpha IS INITIAL THEN '' ELSE lv_test ). " ABCDEFG
之后的第一个操作数派生的,因此输出的长度是根据第一个操作数的长度来限制的。最后一行正确地指定我们希望看到一个字符串作为结果,并忽略第一个操作数具有的任何类型。由于推断类型的方式,您更有可能在嵌套语句中看到这一点。大多数程序员总是使用完全类型化的变量,这意味着像前两个语句中的错误很少见。
THEN
操作数类型非常方便,当然可以加快编程速度,但你需要记住它实际上在做什么,否则就有可能遇到像这样的奇怪错误。这些最后的例子显示了当你依赖一个未指定的类型并且传入的值与你期望的类型不同时会发生什么,但结果并不总是明显不正确,特别是因为这可能发生在所有数据类型,而不仅仅是CLIKE。特别是在无法查看中间对象类型的嵌套语句中,这可能非常难以跟踪。
#