2016-12-03 2 views
1

Minimaliste Exemple:fonction de transformation égale poignées pour une autre fonction égale poignées

classdef MyClass 
properties 
    arr 
    handArr 
end 
properties(Dependent) 
    rowAcc 
    colAcc 
end 
methods 
    function obj = MyClass(arr, handRow, handCol) 
     obj.arr = arr; 
     obj.handArr{1} = handRow; 
     if ~isequal(handRow, handCol) 
      obj.handArr{2} = handCol; 
     end 
    end 
    function r = get.rowAcc(obj) 
     r = obj.handArr{1}(obj.arr); 
    end 
    function c = get.colAcc(obj) 
     c = obj.handArr{end}(obj.arr); 
    end 
end 
end 

Supposons maintenant que je passe des fonctions égales au constructeur, je veux l'accès de ligne et col serait également le même:

[email protected](x)@(y) y; 
x=MyClass(1, f, f); 
isequal(x.rowAcc, x.colAcc) //should be 1 

Est-ce possible?

J'ai une bonne raison de cette exigence « fou »:

J'ai plusieurs algorithmes qui fonctionnent avec plus de 100 Mo d'entrée et prend ces deux fonctions en entrée, et quand ils sont égaux, ils peuvent être optimisés très efficacement; appeler les algorithmes dont j'ai besoin pour effectuer des transformations sur les fonctions d'entrée qui sont encapsulées dans cette classe. Je ne peux pas changer les algorithmes (pas mon code) et ils utilisent isequal sur leurs propres fonctions à expédier.

Répondre

2

Deux variables pointant vers la même fonction anonyme sont considérés comme égaux

f = @(x)x; 
g = f; 

isequal(f, g) 
% 1 

Cependant, si vous définissez les fonctions anonymes à des moments différents, ils ne sont pas considérés comme étant égaux parce que les espaces de travail internes du deux fonctions peuvent différer.

f = @(x)x; 
g = @(x)x; 

isequal(f, g) 
% 0 

Pour que votre déclaration de propriété égales poignées, vous pourriez avoir une propriété « ombre » (accessors_) qui met en cache les accesseurs et vous mettre à jour ces valeurs mises en cache chaque fois que la propriété arr est modifiée.

classdef MyClass 

    properties 
     arr 
     handArr 
    end 

    properties (Access = 'protected') 
     accessors_  % An array of accessor functions for rows & columns 
    end 

    properties (Dependent) 
     rowAcc 
     colAcc 
    end 

    methods 
     function set.arr(obj, value) 
      % Set the value 
      obj.arr = value; 

      % Update the accessors_ 
      self.accessors_ = obj.handArr{1}(obj.arr); 

      % Only assign another accessor if we have a second one 
      if numel(obj.handArr) > 1 
       self.accessors_(2) = obj.handArr{2}(obj.arr); 
      end 
     end 

     function res = get.rowAcc(obj) 
      res = obj.accessors_(1); 
     end 

     function res = get.colAcc(obj) 
      % If only one was stored, this will return a duplicate of it 
      res = obj.accessors_(end); 
     end 
    end 
end 

Cela a aussi l'avantage supplémentaire que vous n'êtes pas en train de créer poignées fonction chaque fois que sont récupérés colAcc et rowAcc.

+0

Merci encore pour une autre excellente réponse! –