【问题标题】:How to define a constant in a Matlab class?如何在 Matlab 类中定义常量?
【发布时间】:2018-12-06 17:16:23
【问题描述】:

我想创建一个 Matlab 枚举类,其方法是根据每个枚举的对应数值从表中查找值。这是我得到的:

classdef testclass < uint8
    enumeration
        enum1 (1)
        enum2 (2)
        enum3 (3)
    end

    A = [100 200 300;101 202 303;111 222 333];

    methods
        function retval = getval(obj1,obj2)
            retval = testclass.A(obj1,obj2);
        end
    end
end

到目前为止,我已经尝试过:

  • 不从 uint8 继承属性,并将 properties 块添加到具有矩阵 A 的类(我希望它是常量)和一个属性 B,我希望它是对应的数字到每个枚举。我收到一条错误消息,说第一个枚举(可能其他每个枚举也是)在其定义中有太多参数。

  • 上面的代码。我在包含 A 的行中收到一个错误,说这是一个意外的 MATLAB 表达式。

  • 不从 uint8 继承属性并添加两个 properties 块,因为如果我定义两个属性,我认为 Matlab 会期望每个枚举定义有两个参数。第一个properties 块是常量,第二个在“属性”之后没有任何内容。这也不起作用。

  • getval 函数内定义矩阵A。这可行,但我希望 A 可用于类中的其他方法。

如何定义类中每个方法都可用的变量?

【问题讨论】:

  • 您应该解释并举例说明用例:您希望如何调用类以及结果输出应该是什么。你解释了你尝试了什么,但没有解释你想要什么,目前还不是很清楚。
  • @Hoki 我希望能够定义两个变量,比如a=testclass.enum1b=testclass.enum3。然后我希望能够调用 getval 函数,该函数在索引 (a,b) 处查找 A 中的值,在这种情况下相当于 A(1,3)。该函数应返回 A(1,3) 处的值。

标签: matlab class enums


【解决方案1】:

我发现您的代码存在三个问题。

  1. 我不知道这是否重要,取决于你在 A 中的值,但你不能用 uint8 表示超过 255 的数字;如 300、303、333。所以你需要在 A 矩阵中使用 uint16 或更小的值。
  2. 我不太明白为什么要将 obj1 和 obj2 作为输入的意图。如果您需要两个参数,我的解决方案将需要修改。
  3. 您的类和构造方法应该具有相同的名称。

我想这就是你所追求的:

>> en = getval.enum1
>> en.a
ans = 
   1x3 uint16 row vector
   101 202 303
>> en.a*2
ans = 
   1x3 uint16 row vector
   202 404 606

classdef getval
    enumeration
        enum1 (1)
        enum2 (2)
        enum3 (3)
    end
    properties
        a
    end

    methods
        function retval = getval(a)            
            A = uint16([100 200 300;101 202 303;111 222 333]);
            retval.a = A(a,:);
        end
    end
end

【讨论】:

  • 在我的用例中,A 实际上是一个包含字符串的元胞数组,而且由于我需要的枚举数少于十二个,因此使用 uint8 不会造成问题。 getval 方法确实需要两个参数,因为必须引用两个索引才能返回存储在单个单元格中的字符串。您的第三点是我遗漏的关键内容之一;对我来说,必须在类定义中定义构造方法似乎是多余的,但我想它允许您定义在声明每个枚举时不必设置的其他类属性(如常量)。
  • @zaen 所以你不要求返回的变量是 uint8 吗?如果你想返回一个字符串,为什么不在你的例子中包含它?
【解决方案2】:

或者,

>> en = getval.enum1
>> en.A
ans = 
   1x3 uint16 row vector
   101 202 303
>> en.A*2
ans = 
   1x3 uint16 row vector
   202 404 606

classdef getval
    enumeration
        enum1 (100,200,300)
        enum2 (101,202,303)
        enum3 (111,222,333)
    end
    properties
        A
    end
    methods
        function retval = getval(a,b,c)            
            retval.A = uint16([a,b,c]);
        end
    end
end

【讨论】:

    【解决方案3】:

    很遗憾,您不能在继承的枚举类上定义属性。相反,您可以在枚举类(例如“double”)上定义一个函数,该函数将返回一些基础值。然后你可以使用这个值来引用一个常量。请看下面的例子:

    类:

    classdef testclass
        enumeration
            enum1
            enum2
            enum3
        end
        properties(Constant)
            A = [100 200 300;101 202 303;111 222 333];
        end
        methods
            function retval = getval(obj1,obj2)
                retval = testclass.A(double(obj1),double(obj2));
            end
            function retval = double(obj)
                if obj == testclass.enum1
                    retval = 1;
                elseif obj == testclass.enum2
                    retval = 2;
                elseif obj == testclass.enum3
                    retval = 3;
                end
            end
        end
    end
    

    运行:

    A = testclass.enum1
    B = testclass.enum2
    getval(A,B)
    

    【讨论】:

    • 这很有效,并且可能是最好的方法。我的解决方案/kludge 是创建一个不继承的类,然后为每个不带参数的常量定义一个静态方法,只返回常量的值。 getval 方法检查矩阵 A 是否从 mat 文件中加载,如果不是,则加载它并返回相应索引处的值。
    猜你喜欢
    • 2012-02-19
    • 2020-01-15
    • 2010-10-03
    • 2017-10-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多