2016-07-23 13 views
5

Załóżmy, że mam funkcję zdefiniowaną w foo.m. Ta funkcja może przyjmować parametr thing typu struct. Po wprowadzeniu foo zmian w thing, chcę "zablokować" thing, aby nie można było już zmienić. W gruncie rzeczy chcę, żeby była stała. Chcę to zrobić, aby upewnić się, że nie zostanie zmodyfikowany w dalszej kolejności. Jak to zrobić w Matlab?Jak utworzyć stałą strukturę Matlaba po jej utworzeniu?

Odpowiedz

4

Rozwiązanie 1: Dobre, jeśli nie wiesz, co stanowić będzie miał swoją struct z góry

Mogłabyś „capture”, że zmienna z anonimową uchwytu funkcji i odnoszą się tylko do konstrukcji z tym od teraz na. Anonimowy uchwyt funkcji przechwytuje stan obszaru roboczego w momencie jego utworzenia. Będziesz mógł uzyskać dostęp do jego elementów tak, jakby był oryginalną strukturą, ale jeśli spróbujesz do tego przypisać, wygenerujesz błąd.

E.g.

>> S_.a = 1; 
>> S_.b = 2; 
>> S = @() S_; 
>> S_.a = 3; 
>> S_ 
S_ = 
    scalar structure containing the fields: 
    a = 3 
    b = 2 
>> S() 
ans = 
    scalar structure containing the fields: 
    a = 1 
    b = 2 

To prawie identyczny w składni, z wyjątkiem irytacji, że będziesz musiał zadzwonić go (). Użyłem go na terminalu tutaj, ale oczywiście można go również łatwo wykorzystać w kontekście funkcji.

Małe zastrzeżenie; jeśli użytkownik ponownie zdefiniuje i nadpisze anonimową funkcję, oczywiście, ten backfires, ponieważ odziedziczy on każdą nową przestrzeń roboczą, do której miał dostęp w czasie redefinicji.

Rozwiązanie 2: Dobra, jeśli wiesz formularzu struct z wyprzedzeniem:

Załóżmy, z góry wiadomo, że struktura będzie zawierać tylko pola a i b. Utwórz klasę o tych samych właściwościach ograniczających "SetAccess", np.

classdef ConstStruct 
    properties (GetAccess = 'public', SetAccess = 'private') 
    a 
    b 
    end 

    methods 
    %constructor 
    function obj = ConstStruct(S) 
     obj.a = S.a; 
     obj.b = S.b; 
    end 
    end 
end 

Następnie w głównym kodzie:

>> MyStruct = struct('a',1,'b',2) 
MyStruct = 
    a: 1 
    b: 2 
>> MyStruct = ConstStruct(MyStruct) 
MyStruct = 
    ConstStruct with properties: 
    a: 1 
    b: 2 
>> MyStruct.a 
ans = 
    1 
>> MyStruct.a = 2 
You cannot set the read-only property 'a' of 'ConstStruct'. 
+0

@physmom Zaktualizowałem z bardziej eleganckim rozwiązaniem, zakładając, że znasz wcześniej formę swojej struktury. –

+0

Naprawdę spróbuję tej metody "casting to object". Wydaje się to być bardzo zbliżone do tego, czego szukałem ... chociaż nie podoba mi się pomysł zdefiniowania gdzieś "lustrzanego" obiektu. – physmom

+0

Dlatego użyłem tej samej nazwy zmiennej, aby nadpisać starą strukturę. Dobra praktyka programistyczna zwykle ostrzega przed tą samą zmienną trzymającą różne typy, ale myślę, że w tym przypadku możesz zrobić wyjątek :) –

5

Należy

  1. zdefiniować zmienną w funkcji jako persistent
  2. zablokować funkcję w pamięci przy użyciu mlock.

mlock blokuje aktualnie działającą funkcję w pamięci, aby kolejne funkcje clear nie usuwały jej. Zablokowanie funkcji w pamięci zapobiega także ponownemu inicjowaniu wszystkich stałych zmiennych zdefiniowanych w pliku.

+0

inne rozwiązanie, jeśli jesteś szczęśliwy, aby użyć kodu obiektowego, jest, aby czynność funkcję członka, który inicjalizuje właściwość z atrybutem „stałej” –

+0

faktycznie o tym myślę, myślę, że obaj źle zinterpretowaliśmy pytanie OP. Myślę, że są po "zablokowaniu" zmiennej, gdy wciąż znajdują się w pierwszym przejściu funkcji. –

+0

Dobrze wiedzieć, +1, ale odpowiedź @Tasos Papastylianou była bliższa temu, czego szukałem. Nie wiedziałem o "mlocku"! – physmom

Powiązane problemy