6

我将一组匿名函数分组为一个结构和该结构中的一些变量。有没有办法引用“自我”,即自己的结构?我想要完成的是让一个函数根据成员变量返回一些值。为简单起见,假设我有一个struct a,其中

a.value_1 = 3;
a.value_2 = 2;
a.sum = @()(self.value_1 + self.value_2)

在 MATLAB 中有类似的可能吗?

4

3 回答 3

10

在MATLAB 中引入面向对象编程之前(包括classdef-style过时的 @-directory样式类),可以使用闭包和嵌套函数(当然缺少继承)创建轻量级对象。这个概念也存在于其他语言中。

这是一个例子:

function s = mystruct()
    s = struct('value_1',[], 'value_2',2, 'sum',@mysum);
    s.value_1 = 3;

    function out = mysum()
        out = s.value_1 + s.value_2;
    end
end

用作:

>> s = mystruct()
s = 
    value_1: 3
    value_2: 2
        sum: @mystruct/mysum
>> s.value_1 = 10;     % NOTE: this wont do what you expect!
>> s.sum()
ans =
     5

请注意,创建闭包时会立即捕获变量(如果您愿意,函数有自己的私有副本)。因此,如果您从返回的结构中更改其中一个公开的字段,它将不会反映在封闭状态中(将它们视为只读属性)。

一种解决方案是提供访问器方法:

function obj = mystruct()
    % think of those as private properties
    value_1 = 3;
    value_2 = 2;

    % returned object (this or self)
    obj = struct();

    % public accessors for properties
    obj.value_1 = @accessValue1;
    function out = accessValue1(in)
        if nargin > 0, value_1 = in; end
        out = value_1;
    end
    obj.value_2 = @accessValue2;
    function out = accessValue2(in)
        if nargin > 0, value_2 = in; end
        out = value_2;
    end

    % member method
    obj.sum = @mysum;
    function out = mysum()
        out = value_1 + value_2;
    end
end

所以现在我们可以说:

>> s = mystruct()
s = 
    value_1: @mystruct/accessValue1
    value_2: @mystruct/accessValue1
        sum: @mystruct/mysum
>> x = s.value_1();   % get
>> s.value_1(10);     % set
>> s.sum()
ans =
    12

这开始看起来像当前推荐的创建类的方法:

classdef mystruct < handle
    properties
        value_1 = 3;
        value_2 = 2;
    end
    methods
        function out = sum(obj)
            out = obj.value_1 + obj.value_2;
        end
    end
end

以类似的方式使用:

>> s = mystruct()
s = 
  mystruct with properties:

    value_1: 3
    value_2: 2
>> s.value_1 = 10;
>> s.sum
ans =
    12

我们还可以像以前一样定义 get/set访问方法..

于 2013-08-12T16:14:19.900 回答
2

这似乎可行,但我认为您应该创建 a 而class不是 astruct来执行此操作:

a.value_1 = 3;
a.value_2 = 2;

a.sum = @(x)(x.value_1 + x.value_2)

a.sum(a)
于 2013-08-12T14:18:50.450 回答
0

有了这个变化

a.value_1 = 3;
a.value_2 = 2;
a.sum = @()(a.value_1 + a.value_2)

然后a.sum()返回5。但是当您稍后更改其中一个值时会发生什么,例如 set a.value_1 = 5?现在a.sum()返回......仍然5。传递给匿名函数的参数在实例化时进行评估。如果您希望第二种行为正常工作,则需要使用class。有关更多信息,请参阅我对这个问题的回答。像您一样使用函数句柄的唯一原因是避免在需要之前评估和存储函数的大量输出。

于 2013-08-12T14:35:14.053 回答