【问题标题】:VBScript conditional short-circuiting workaroundVBScript 条件短路解决方法
【发布时间】:2008-09-12 17:42:05
【问题描述】:

我有一个必须维护的大型经典 ASP 应用程序,但我反复发现自己因缺乏短路评估能力而受挫。例如,VBScript 不会让你逍遥法外:

if not isNull(Rs("myField")) and Rs("myField") <> 0 then
...

...因为如果 Rs("myField") 为 null,则在第二个条件中会出现错误,将 null 与 0 进行比较。所以我通常会这样做:

dim myField
if isNull(Rs("myField")) then 
    myField = 0
else
    myField = Rs("myField")
end if

if myField <> 0 then
...

显然,冗长程度令人震惊。环顾这个大型代码库,我发现最好的解决方法是使用原始程序员编写的一个名为 TernaryOp 的函数,它基本上移植了类似三元运算符的功能,但我仍然坚持使用不会在功能更全面的语言中是必要的。有没有更好的办法? VBScript中确实存在短路的一些超级秘密方式?

【问题讨论】:

    标签: asp-classic vbscript


    【解决方案1】:

    嵌套的 IF(只是稍微不那么冗长):

    if not isNull(Rs("myField")) Then
       if Rs("myField") <> 0 then
    

    【讨论】:

      【解决方案2】:

      也许不是最好的方法,但它确实有效...此外,如果您使用的是 vb6 或 .net,您也可以使用不同的方法来转换为正确的类型。

      if cint( getVal( rs("blah"), "" ) )<> 0 then
        'do something
      end if
      
      
      function getVal( v, replacementVal )
        if v is nothing then
          getVal = replacementVal
        else
          getVal = v
        end if
      end function
      

      【讨论】:

        【解决方案3】:

        我总是使用 Select Case 语句来短路 VB 中的逻辑。有点像..

        Select Case True
        
        Case isNull(Rs("myField"))
        
            myField = 0
        
        Case (Rs("myField") <> 0)
        
            myField = Rs("myField")
        
        Case Else
        
            myField = -1        
        
        End Select
        

        我的语法可能已经关闭了一段时间。如果第一种情况出现,则忽略其他所有情况。

        【讨论】:

          【解决方案4】:

          如果写成两个内联IF语句,可以实现短路:

          if not isNull(Rs("myField")) then if Rs("myField") <> 0 then ...
          

          但您的then 操作也必须出现在同一行。如果您需要then 之后的多个语句,您可以将它们用: 分隔或将您的代码移动到您可以调用的子例程中。例如:

          if not isNull(Rs("myField")) then if Rs("myField") <> 0 then x = 1 : y = 2
          

          或者

          if not isNull(Rs("myField")) then if Rs("myField") <> 0 then DoSomething(Rs("myField"))
          

          【讨论】:

            【解决方案5】:

            或者我的问题结尾有误。你的意思是像 VB 中的iIf() 这样的东西吗?这对我有用:

            myField = returnIf(isNothing(rs("myField")), 0, rs("myField"))
            

            returnIf() 是这样的函数:

            function returnIf(uExpression, uTrue, uFalse)
                if (uExpression = true) then returnIf = uTrue else returnIf = uFalse : end if
            end function
            

            【讨论】:

            • 但是rs("myField") 不是在调用returnIf 时计算的吗?在那种情况下,它不是短路评估......
            • 不,这个函数在你需要它们之前不会解析输入,所以它们不会被评估(尽管你可以将表达式作为第二个或第三个参数传递,在这种情况下它会得到即时评估)。这就是僵尸线程——这个回复比 10 岁还差一个月!
            • 尽管这个(僵尸线程)我正在寻找答案......是的,它是实际工作所需要的......
            【解决方案6】:

            是的,这不是最好的解决方案,但我们使用的是这样的

            function ReplaceNull(s)
                if IsNull(s) or s = "" then
                    ReplaceNull = "&nbsp;"
                else
                    ReplaceNull = s
                end if
            end function
            

            【讨论】:

              【解决方案7】:

              如果有的话,我的朋友 -- TernaryOp 是你唯一的希望。

              【讨论】:

              • 经典 VB 也没有真正的三元运算,只有 IIf() 函数(立即 if)。但即使这仍然是一个函数,所以 所有 函数参数必须在传递给函数之前进行评估。
              【解决方案8】:

              想到两个选项:

              1) 使用len()lenb()发现变量中是否有数据:

              if not lenb(rs("myField"))=0 then...
              

              2) 使用返回布尔值的函数:

              if not isNothing(rs("myField")) then...
              

              isNothing() 是这样的函数:

              function isNothing(vInput)
                  isNothing = false : vInput = trim(vInput)
                  if vartype(vInput)=0 or isEmpty(vInput) or isNull(vInput) or lenb(vInput)=0 then isNothing = true : end if 
              end function
              

              【讨论】:

                【解决方案9】:

                您也许可以只使用Else 来捕获空值、“”等。

                If UCase(Rs("myField")) = "THING" then
                  'Do Things
                elseif UCase(Rs("myField")) = "STUFF" then
                  'Do Other Stuff
                else
                  'Invalid data, such as a NULL, "", etc.
                  'Throw an error, do nothing, or default action
                End If
                

                我已经在我的代码中对此进行了测试,它目前正在运行。不过可能并不适合每个人的情况。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-09-16
                  • 2013-11-08
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多