Select Case
 

基本实施

dim i as integer  dim i as integer

    scope
select case i + 123   dim temp as integer = any
     temp = i + 123

case 1     if( temp <> 1 ) then goto cmplabel1
     scope
 print "1"    print "1"
     end scope
     goto endlabel

case 2     cmplabel1:
     if( temp <> 2 ) then goto cmplabel2
     scope
 print "2"    print "2"
     end scope
     goto endlabel

case else    cmplabel2:
     scope
 print "else"    print "else"
     end scope

end select    cmplabel3:    '' unused only because in this example the last CASE is not conditional
     endlabel:
    end scope

  • SELECT CASE
    • 打开隐式的外部范围
    • 声明temp var
      • 当使用STATIC的过程中,temp var将变为静态
      • FB_SYMBATTRIB_TEMP从temp var中删除,因为它的寿命比只有一个语句长
    • 发出作业
    • 宣布结束标签
  • 每个案例
    • 如果有一个以前的CASE
      • 关闭以前的CASE范围
      • 发出跳转到终端标签
    • 发出此CASE的标签
    • 发出条件分支跳转到下一个CASE如果不符合CASE条件
    • 打开CASE的范围
    • CASE ELSE不发出条件分支
    • 一旦使用了CASE ELSE,则不允许使用更多的CASE块
  • END SELECT
    • 关闭以前的CASE范围
    • 在最后发出一个额外的CASE标签(没有CASE来了,但是这允许最后一个CASE跳转到最后,如果它是一个有条件的CASE。最后一个CASE可以跳转到SELECT的结束标签,但这需要一些特殊的情况处理代码。)
    • 发出终端标签
  • 任何EXIT SELECT将立即跳到结束标签


SELECT CASE on strings / zstrings / fixstrs

dim s as string   dim s as string

    scope
select case s + "1"   dim temp as string

     fb_StrAssign( temp, s )
     fb_StrConcatAssign( temp, "1" )

case "1"    if( fb_StrCompare( temp, "1" ) <> 0 ) then goto cmplabel1
     scope
 print "1"    print "1"
     end scope
     goto endlabel

     cmplabel1:
end select    endlabel:
     fb_StrDelete( temp )    '' destroying the temp var at scope end
    end scope

    fb_StrDelete( s )

  • 字符串/ zstring / fixstr表达式上的SELECT CASE使用字符串temp var
    • 可能是因为最简单
    • 知道字符串长度可能会加速以下比较
    • 动态内存赋值也可能会减慢
  • 字符串temp var在范围结束或范围中断(例如,从CASE块中到达END SELECT或EXIT FUNCTION)

SELECT CASE on wstrings

dim w as wstring * 10   dim w as wstring * 10

     scope
select case w + wstr( "1" )   dim temp as wstring ptr

      dim tempexpr as wstring ptr = w + wstr( "1" )
      temp = fb_WstrAlloc( fb_WstrLen( tempexpr ) )
      fb_WstrAssign( temp, tempexpr )

case wstr( "1" )    if( fb_WstrCompare( temp, wstr( "1" ) ) <> 0 ) then goto cmplabel1
      scope
 print "1"     print "1"
      end scope
      goto endlabel

      cmplabel1:
end select     endlabel:
      fb_WstrDelete( temp )    '' destroying the temp var at scope end
     end scope

  • 与zstrings中的SELECT CASE类似,对于wstring表达式,wstring是动态赋值的
  • temp wstring的处理非常像一个动态wstring对象
    • 它是一个类型为WCHAR PTR的VAR符号
    • 标有FB_SYMBSTATS_WSTRING
    • 这允许ctor / dtor检查来识别它并给它所需的治疗
  • 这样,在范围结束或范围中断时,temp wstring被破坏


SELECT CASE without temp var

当提供给select语句的表达式只是一个简单的变量访问时,则不需要创建临时变量。在这种情况下,给定的变量本身将用于每个case语句的比较。例如:

dim i as integer  dim i as integer

    scope
select case i

case 1     if( i <> 1 ) then goto cmplabel1
     scope
 print "1"    print "1"
     end scope
     goto endlabel

end select    cmplabel1:
     endlabel:
    end scope