MATLAB - create reference (handle?) to variable

前端 未结 3 1538
北恋
北恋 2021-02-02 03:13

Suppose I have the following class:

classdef myClass < handle
    properties
        A = 1
    end
    methods
        function obj = myClass(val)
                   


        
3条回答
  •  情歌与酒
    2021-02-02 03:32

    I don't think there is anything that will do exactly as you want, given all your constraints.

    However, I'm not really clear on your notational issues. Why do you want to retain the notation w.A while you are considered about value not changing? Keeping the notation w.A similar is not a real issue.

    Using some modified code, I can produce following execution:

    >> q = myClass(10);
    >> q.A = 15;
    >> w = q;
    >> w.A
        15
    >> value = w.Aref;
    >> value()
        15
    >> w.A = 20;
    >> value()
    ans =
        20
    

    But there is no way around the notation value() as that is the turning point of the implementation; which I think is the closest you can get to what you want. You get the behavior above when you use the following code to implement myClass:

    classdef myClass < handle
    properties
        A = 1;
    end
    methods
        function obj = myClass(val)
            obj.A = val;
        end
        function a = Aref(obj)
            a =  @()(obj.A);
        end
    end
    end
    

    So you see that the Aref method actually returns a function handle which fetches the value from the object. This also means that this reference is read-only!

    Also note that you will have to instantiate a myClass instance before you are able to get the value of A (where would you get the value of A from otherwise?). This instance does not have to be visible inside your current workspace (e.g. another function scope), since the myClass instance is stored within the function handle value.

    Drawback of this method is that you only get a read-only reference, you will have to use the call value() to get the actual value instead of the function handle (so that changes the notation, but not the one you wanted to keep (or at least it can be made so by substituting A in my code by Aval and renaming Aref to A). Another drawback is that resolving value might be a bit slower than simply resolving a variable (whether that's a problem will depend on your usage of value()).

    If you want some of the notations changed, this can be done by using dependent properties:

    classdef myClass < handle
        properties (Access=private)
            Aval = 1;
        end
        properties (Dependent)
            A;
        end
        methods
            function obj = myClass(val)
                obj.A = val;
            end
            function a = get.A(obj)
                a =  @()(obj.Aval);
            end
            function set.A(obj,value)
                obj.Aval = value;
            end
        end
    end
    

    The equivalent execution of above is given by:

    >> q = myClass(10);
    >> q.A = 15;
    >> w = q;
    >> w.A()
        15
    >> value = w.A;
    >> value()
        15
    >> w.A = 20;
    >> value()
    ans =
        20
    

    edit: I thought of another way to implement this, which is simpler (i.e. just keep the class of your original post) but it requires you to change the code in other places. The basic idea behind it is the same as the first ones, but without encapsulating it in the object itself (which makes the object cleaner, IMHO).

    >> q = myClass(10);
    >> q.A = 15;
    >> w = q;
    >> w.A()
        15
    >> value = @()(w.A);
    >> value()
        15
    >> w.A = 20;
    >> value()
    ans =
        20
    

提交回复
热议问题