【问题标题】:Invoke Matlab `loadobj` when input is an object, *before* it becomes a `struct`当输入是一个对象时调用 Matlab `loadobj`,*before* 它变成一个`struct`
【发布时间】:2018-12-25 16:20:26
【问题描述】:

我最初涉足loadobj:我找到了code pattern and explanation

如果load 函数遇到错误,load 将传递loadobj struct 而不是对象

我的加载错误来自使用尚未使用的属性的设置器 在加载过程中被分配。我想定义一个loadobj 避免上述错误并避免从struct 复制的方法 共。我通过按以下顺序设置属性来做到这一点 它们是用来设置的。使用上面的代码模式 网页:

methods(Static)

   function oOut = loadobj(oIn)

      if isstruct( oIn ) % Diagnostic breakpoint set here
         error('Load failed');
      end % if

      % Example code pattern shows input object assigned to output
      % object, but I want to control the order in which
      % properties are assigned to

      oOut.TstepPrYr = oIn.TstepPrYr;
      oOut.TwinYrs = oIn.TwinYrs;
      oOut.Twin1sidePadYrs = oIn.Twin1sidePadYrs;

      % The following properties should have been set by setters
      %     TwinPaddedYrs
      %     TwinPaddedDays
      %     TstepDays
      %     TwinPaddedTsteps % Not used

      % There are also many other properties.  With the key
      % properties set, I should now be able to copy the rest in
      % one shot.

      oOut = oIn;

   end % function

end % methods(Static)

在顶部,我捕获了输入参数是struct 的情况。 这样的条件会 表示当输入参数是真正的对象时加载失败。 在这种情况下,我不应该继续 - 我应该修复 loadobj 代码。

由于loadobj 以正确的顺序将值分配给属性,它 永远不应该失败,因此,永远不应该再次调用它 struct 参数。不幸的是,我仍然在 setter 中出错 由于不存在的属性值。我在顶部放了一个断点 的loadobj,看看输入参数是否确实是struct——它是! 所以loadobj 可能甚至没有被一个真正的对象调用。 我猜想 Matlab 的默认加载代码(和加载顺序)是 被使用。根据loadobj help的顶部,这是 不是我所期望的。

有人可以建议我可以做些什么来进一步解决这个问题吗? 以防万一,我的课程源自matlab.mixin.Copyable

观察到的奇怪行为:如果我使用调试器继续执行上述 error 语句,它会生成 Matlab 警告而不是错误。但它仍然存在。

【问题讨论】:

  • 你实现saveobj了吗? load 构建您的对象,然后调用 loadobj。如果构建对象失败,它会使用结构调用loadobj。在您的情况下,构建对象最初会失败。定义一个saveobj,它输出一个包含这三个字段的结构。
  • 我还没有实现saveobj,但根据我的阅读,使用loadobj 应该没有必要。为了避免多余的代码,我只是尝试实现loadobj,这(显然)可以完成,甚至不一定会气馁。我认为这里的问题只是了解loadobj 的工作原理。它是否首先用对象调用,如果失败则重新调用?示例模式包含 if isstruct... 的事实似乎正是暗示了这一点,loadobj 帮助似乎也暗示了这一点。
  • 是的,它看起来就是这样做的。但是如果它用你的类的对象调用你的函数,它已经构造了它。那你为什么需要重新构建它呢?这个loadobj 有什么意义?鉴于没有loadobj,您的对象无法构建,您必须将结构传递给loadobj。你可以通过定义一个saveobj来做到这一点。

标签: matlab oop


【解决方案1】:

我相信您需要在开始初始化属性之前将oOut = oIn; 行移动到。默认情况下,变量oOut 未初始化为对象;当您开始使用点符号分配属性时,它会初始化为结构。或者,您可以通过调用构造函数来初始化 oOut,然后从 oIn 移动属性。

loadobj 方法的末尾添加oOut = oIn; 行只是将oOut 设置为传递的未更改的oIn 对象,无需任何修改。

【讨论】:

  • 该死。回想起来,你的 lat 句子是如此明显。但是我对前面的段落感到困惑。我对loadobj的理解是load首先以保存的对象作为输入调用它,如果失败则以对象的structs版本再次调用。这不正确吗?无论如何,我遇到了一个谜:我不再遇到错误。我尝试了clear allclear functionsclear classes 的所有组合,并重新启动 Matlab 以重新创建条件。
  • 虽然上面听起来是好事,但实际上很糟糕,这意味着无法产生已知问题,因此无法进行故障排除。当我负担不起绕道时,它会抬起头来。我知道它会,因为原因是已知的,我还没有修复它。 :(
  • @user36800:这就是我认为该过程的工作方式:load 尝试加载对象数据并构造对象。如果成功,该对象将传递给任何现有的 loadobj 方法以进行任何其他设置(即重新生成文件 ID 等)。如果加载和对象构造失败,或者对象已被saveobj 例程保存为结构,则将对象数据的结构传递给loadobj,以便它可以尝试自己构造对象。
  • @user36800:至于您重新创建错误的问题,可能是您修改了类定义但没有从工作区中清除旧的类对象,导致一些未定义的行为。如果清理工作区后现在可以正常工作,我就不用担心了。
  • 感谢loadobj 工作。我将建议 TMW 在文档页面中更加明确。至于修改类,我会定期对整个项目进行快照,并且可以将当前代码库与以前的快照进行比较。我找不到任何可以解释问题症状消失的代码差异(都是格式和注释)。我更关心的是无法进行故障排除,因为我现在受制于问题决定再次发生的时机。啊,好吧,欢迎来到...现实,我猜。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2020-12-04
  • 2013-12-09
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2012-05-01
相关资源
最近更新 更多