包含标量分类的自定义类显示为“[1x1分类]”,而不是显示类别

时间:2016-03-09 15:04:50

标签: matlab class oop struct categories

在MATLAB R2014b上,如果if (!require('ti.permissions').hasPermission('android.permission.RECORD_AUDIO')) require('ti.permissions').requestPermissions(['android.permission.RECORD_AUDIO'], function(e) { if (e.success != 0) Ti.API.debug("Permissions OK"); else Ti.API.warn("Permissions denied"); }); (或自定义类)的字段为标量struct,则在显示categorical时,它会显示struct而不是我想要实现的目标,如下所示。

MWE

[1x1 categorical]

输出:

struct.field = categorical({'category'})

我想要的输出:

struct = 
    field: [1x1 categorical]

或:

struct = 
    field: category

我想要这个,因为我正在编写一些具有struct = field: category [1x1 categorical] 属性的类,这些属性总是标量的;因为我根据定义知道这一点,所以我不需要将对象的类别显示为categorical。在显示自定义对象时,我希望它显示该类别。

我可以在我的类方法中重载[1x1 categorical],但后来我需要重写来自disp本身的大量显示代码,而不仅仅是改变标量disp的方式categorical字段显示。

关于如何实现这一目标的任何想法?如果您的答案涉及在类定义中重载struct,那么除了显示disp属性之外,我想看看如何显示对象的其他属性,如普通disp(obj)。我想要的方式。你有任何想法或想法可以帮助我写自己的答案,所以请分享任何。

2 个答案:

答案 0 :(得分:1)

在玩了一段时间之后,我想我终于有了一些可以在自定义类中显示这些标量categorical值的东西。

基本思想是我为保留get的属性重载categorical方法。然后我可以检查调用堆栈以查看正在尝试获取变量值的。如果它是我们重载的disp方法(在我们想要显示我们的类的任何时候调用它),那么我返回类别名称,如果它只是一个标量categorical。否则,我返回属性本身的值(作为categorical)。

由于它依赖于dbstack,它绝对不是最优雅的,但它看起来效果很好。

classdef categoryclass < handle

    properties
        a = categorical({'category'});
    end

    methods
        % Get Method for "a" property
        function res = get.a(self)

            % Get the call stack to determine *what* called this
            stack = dbstack();

            methodname = sprintf('%s.disp', class(self));

            % If it is a scalar and it was called by our overloaded display
            % method, then return the category name
            if isscalar(self.a) && isa(self.a, 'categorical') && ...
                strcmp(methodname, stack(end).name)
                res = categories(self.a);
                res = res{1};
            % Otherwise return just the value itself
            else
                res = self.a;
            end
        end

        % This ensure that disp() shows up in the stack
        function disp(self)
            % Simply call the built-in display function
            builtin('disp', self);
        end
    end
end

现在我们试试这个。

cls = categoryclass()

  categoryclass with properties:

       a: 'category'

检查我们在请求值时,我们实际上获得categorical

class(cls.a)

    ans =  

       categorical

现在更改它的值。

cls.a = categorical({'another category'})

  categoryclass with properties:

       a: 'another category'

现在使用两个类别

cls.a = categorical({'one', 'two'})

  categoryclass with properties:

       a: [1x2 categorical]
  

注意:这似乎只是R2014b和R2015a中的一个问题。它已在所有后续版本中修复。

答案 1 :(得分:0)

已经有一段时间了,但今天我又需要这个了。我想到了另一种显示标量categorical变量的方法。以下示例类可以解决问题。

classdef dispfmtTest < matlab.mixin.Copyable
    properties
        prop = categorical(1) % default value is a scalar categorical
    end
    methods
        function dispfmt(obj) % dispfmtTest object to display format
            obj.prop = char(obj.prop); % convert to char type
        end
        function disp(self)
            obj = copy(self); % copy is provided by superclass
            dispfmt(obj)
            disp@matlab.mixin.Copyable(obj) % call superclass disp
            delete(obj)
        end
    end
end

dispfmtTest类是matlab.mixin.Copyable的子类,而handlecopy的子类。它为disfmtTest类提供prop方法,该方法用于临时创建一个副本,其属性dispfmt的值更改为方法{{1}中所需的任何显示格式}。然后,使用disp提供的常规matlab.mixin.Copyable函数显示对象的修改副本。

演示

运行obj = dispfmtTest会产生

d = 
  dispfmtTest with properties:

    prop: '1'

class(d.prop)产生

ans =
categorical

这是我预期的行为。使用isscalar也可以实现对数组属性的支持。