繁体   English   中英

结果附加或异常

[英]Result attached or exception

假设我有一个 function f应该通过调用g返回attached T 但是, g返回一个detachable T 如果g导致 Void,我想引发这样的异常:

f: T
  do
    if attached g as res then
      Result := res
    else
      raise
    end
  end
  
raise
  do
    (create {DEVELOPER_EXCEPTION}).raise
  end

在此设置中,EiffelStudio 给了我一个错误VEVI: Variable is not properly set. Variable: Result VEVI: Variable is not properly set. Variable: Result f末尾的结果。

实际上, Result 可以在f的末尾为 Void 但在这种情况下执行不应到达f的末尾,应该引发异常。

如何重构代码以获得类似的结果?

如果引发异常的类型无关紧要,则可以使用以下代码:

f: T
    do
        Result := g
        check is_g_attached: attached Result then end
    end

如果引发异常的类型很重要,则可以使用表示该特性永远不会返回的后置条件False来增加特性raise 然后,代码看起来像

f: T
    do
        Result := g
        if not attached Result then
            raise
        end
    end

raise
    do
        (create {DEVELOPER_EXCEPTION}).raise
    ensure
        False
    end

刚刚发现在这种情况下可以使用check

f: T
  do
    if attached g as res then
      Result := res
    else
      raise
    end
    check attached Result then end
  end

但是,我想知道是否有更清洁的方法。

我认为你可以逃脱:

f:T
   do
      check has_g: attached g then Result := g end
   end

如果attached g不是True ,代码自然会中断。 请注意,当我想确保附加诸如g之类的功能时,我会使用此构造。

我还将其编码为:

f:T
   do
      check has_g: attached g as al_result then Result := al_result end
   end

所以,你可能会问:这有什么不同,“al_”前缀是什么?

  1. 第一个示例没有as ____的混乱,这使它更容易阅读和理解(恕我直言)。
  2. “al_”前缀是我遵循的命名约定,其中“al”表示“附件本地”。 作为我的代码的读者,我可以查看变量名并知道变量的声明位置。
  • 如果变量没有前缀,则它是 class 本身的特征参考。

  • 如果前缀是“l_?”,那么我会查看功能local声明。

  • 如果是“al_”,那么我会查看checkif.. then或其他块as关键字。

  • 我也将它用于跨循环,其中ic_? 是一个“迭代游标”本地 object。 我也将此命名约定应用于符号循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM