簡體   English   中英

函數句柄作為類的屬性-Matlab

[英]Function handle as a property of a class - Matlab

我定義了一個類CellArrayHandle,它的唯一屬性是函數句柄的單元格數組:

classdef CellArrayHandle < handle    
    properties
        cel  % cell array of function handles    
    end 
end

假設myHandleCellArrayHandle的一個對象,所以myHandle.cel是函數處理的n乘1單元陣列,即myHandle.cel {I}是一個功能句柄對於i = 1至n。

我想進行一些更新(例如,i = 1),但以下操作無效:

  myHandle.cel{1} = @(x) myHandle.cel{1}(x) + 0.5;

Matlab說“達到了500的最大遞歸限制”,因此它似乎可以理解為無限遞歸。 然而,下面的工作原理:

  f = @(x) f(x) + 0.5;

用於功能句柄f。

似乎當我將函數句柄作為屬性封裝到類中時,上述更新方法將無法工作。

我不明白前者與后者之間的區別。 在這一點上有人可以幫助我嗎? 非常感謝你。

最好的祝福,

坦率

區別源自句柄類語義

您可以將句柄對象分配給多個變量,也可以將其傳遞給函數,而不會導致MATLAB復制原始對象。

或者,借用Highlander的原始思想,當實例化一個句柄類時,“只能有一個”(內存中實例的全局性,您將其分配給所有實例的變量只能創建引用而不是新副本)。

考慮示例腳本:

f = @(x) x;
f = @(x) f(x) + 0.25;
f = @(x) f(x) + 0.50;

b = CellArrayHandle();
b.cel{1} = @(x) x;
b.cel{1} = @(x) b.cel{1}(x) + 0.25;
b.cel{1} = @(x) b.cel{1}(x) + 0.5;

fval = f(1);
bval = b.cel{1}(1);

如果我調試此腳本並在fval求值之前查看堆棧,我會看到:

K>> dbstack
> In @(x)x
  In @(x)f(x)+0.25
  In @(x)f(x)+0.5

因此,Matlab能夠在創建后續f句柄的過程中創建當前f函數句柄的副本,並且可以形成堆棧。

當我對b做同樣的事情時,我得到了:

K>> dbstack
> In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  In @(x)b.cel{1}(x)+0.5
  ...

這是因為每個分配的屬性b使得財產b該值在不創建類的新實例 因此,該賦值本質上是無限遞歸的。

您可以通過不讓類從handle繼承而是從value (默認值)繼承來解決此問題。 通過從classdef刪除< handle ,並重復該dbstack ,我們可以

K>> dbstack
> In @(x)x
  In @(x)b.cel{1}(x)+0.25
  In @(x)b.cel{1}(x)+0.5

這是因為每個分配的屬性b現在使當前的副本b ,實例化一個新的b ,並存儲的舊定義b功能手柄內,形成正確的堆棧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM