Types 是否可以在ABAP中创建选项类型?

Types 是否可以在ABAP中创建选项类型?,types,abap,Types,Abap,ABAP中一个持续的烦恼是,无法区分从未设置的变量和设置为其数据类型初始值的变量,并且通过itab[…]表达式访问内部表失败会抛出CX_SY_itab_LINE_NOT_FOUND,这在运行时处理成本很高 对于枚举类型,可以将第一个变量定义为无效,以防止第一个混淆: TYPES: BEGIN OF ENUM my_bool, invalid, true, false, END OF ENUM my_bool. (不要实际使用此类型作为替换。谓词方法调用的行为方式

ABAP中一个持续的烦恼是,无法区分从未设置的变量和设置为其数据类型初始值的变量,并且通过
itab[…]
表达式访问内部表失败会抛出
CX_SY_itab_LINE_NOT_FOUND
,这在运行时处理成本很高

对于枚举类型,可以将第一个变量定义为
无效
,以防止第一个混淆:

TYPES:
  BEGIN OF ENUM my_bool,
    invalid,
    true,
    false,
  END OF ENUM my_bool.
(不要实际使用此类型作为替换。谓词方法调用的行为方式是,方法
meth
返回
my\u BOOL
将导致
obj->meth()
IF obj->meth()中.
只有在返回
无效时才是真实的,因为如果obj->meth()不是初始值,则谓词方法调用相当于

对于非枚举类型,我们运气不佳。尝试实现类似于从尝试访问某些数据但失败的方法返回的方法会被泛型的弱类型所阻止:

CLASS zcl_option DEFINITION
    FINAL.
PUBLIC SECTION.
  CLASS-METHODS some
    IMPORTING VALUE(val) TYPE any
    RETURNING VALUE(option) TYPE REF TO zcl_option.
  CLASS-METHODS none
    RETURNING VALUE(option) TYPE REF TO zcl_option.
  METHODS is_some
    RETURNING VALUE(is_some) TYPE abap_bool.
  METHODS get
    RETURNING VALUE(val) TYPE ???.
ENDCLASS.
尝试在
get
的返回值中使用泛型类型失败,返回的参数必须是完全类型的


有没有一种方法可以在ABAP中构造类似选项类型的东西,或者更一般的方式?

这就是我想到的。我正要把它扔掉,但它开始看起来并不是100%无用,所以它是这样的:D:D



是的,这是可能的。但是,它不像支持泛型类型的编程语言那样具有类型安全性和方便性

CLASS zcl_optional DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING
        value TYPE simple OPTIONAL.
    METHODS is_available
      RETURNING
        VALUE(result) TYPE abap_bool.
    METHODS put_into
      IMPORTING
        reference TYPE REF TO data.

  PRIVATE SECTION.
    DATA value TYPE REF TO data.

ENDCLASS.

CLASS zcl_optional IMPLEMENTATION.

  METHOD constructor.
    IF value IS SUPPLIED.
      DATA(type_descriptor) =
        CAST cl_abap_datadescr( cl_abap_datadescr=>describe_by_data( value ) ).
      CREATE DATA me->value TYPE HANDLE type_descriptor.
      ASSIGN me->value->* TO FIELD-SYMBOL(<target>).
      <target> = value.
    ENDIF.
  ENDMETHOD.

  METHOD is_available.
    result = xsdbool( me->value IS BOUND ).
  ENDMETHOD.

  METHOD put_into.
    IF value IS BOUND.
      ASSIGN value->* TO FIELD-SYMBOL(<source>).
      ASSIGN reference->* TO FIELD-SYMBOL(<target>).
      <target> = <source>.
    ENDIF.
  ENDMETHOD.

ENDCLASS.
问题在于返回可选值的方法无法描述内容的实际类型

METHODS do_something
  RETURNS
    VALUE(result) TYPE REF TO zcl_optional. " int4 or string?
因为内部表总是空的,没有行。所以你的整个想法毫无意义


设置初始值不会阻止您获得
CX\u SY\u ITAB\u LINE\u not\u FOUND
异常。

我认为没有比您的建议更好的答案了,您可能只会获得关于如何对其进行常规编码的自以为是的答案(例如,通过使用继承并将子类中的值定义为只读属性等)也许你应该给出你想要使用它的上下文,因为它目前看起来非常理论化,这样才能得到更精确的答案。@SandraRossi虽然我心里有一个具体的上下文,但我发现这种类型通常很有用,可以从查询可能存在或不存在的资源的方法返回,也就是说,不存在本身不是一种例外状态。(示例:获取类的TADIR条目(如果存在)。例如,许多由BSP框架之类的东西生成的类没有TADIR条目,但这不是错误。)
DATA(optional_integer) = NEW zcl_optional( 42 ).
cl_abap_unit_assert=>assert_true( optional_integer->is_available( ) ).

DATA integer_variable TYPE i.
optional_integer->put_into( REF #( integer_variable ) ).
cl_abap_unit_assert=>assert_equals( act = integer_variable exp = 42 ).

DATA(optional_string) = NEW zcl_optional( `abc` ).
cl_abap_unit_assert=>assert_true( optional_string->is_available( ) ).

DATA string_variable TYPE string.
optional_string->put_into( REF #( string_variable ) ).
cl_abap_unit_assert=>assert_equals( act = string_variable exp = `abc` ).

DATA(empty_optional) = NEW zcl_optional( ).
cl_abap_unit_assert=>assert_false( empty_optional->is_available( ) ).

DATA another_variable TYPE string.
empty_optional->put_into( REF #( another_variable ) ).
cl_abap_unit_assert=>assert_initial( another_variable ).
METHODS do_something
  RETURNS
    VALUE(result) TYPE REF TO zcl_optional. " int4 or string?