2016-07-23 4 views
5

Angenommen, ich habe eine Funktion definiert in foo.m. Diese Funktion kann einen Parameter thing vom Typ struct annehmen. Sobald foo Änderungen an thing vornimmt, möchte ich thing sperren, so dass es nicht mehr geändert werden kann. Ich möchte es im Wesentlichen konstant machen. Ich möchte dies tun, um sicherzustellen, dass es nicht weiter unten geändert wird. Wie mache ich das in Matlab?Wie wird eine Matlab-Struktur konstant gemacht, wenn sie bereits erstellt wurde?

Antwort

4

Lösung 1: Gut, wenn Sie nicht wissen, was Ihre Struktur im Voraus hat bilden

Sie könnte ‚Capture‘ diese Variable mit einem anonymen Funktionsgriff und nur mit, dass auf Ihre Struktur bezieht ab sofort auf. Ein anonymer Funktionszeiger erfasst den Status des Arbeitsbereichs zum Zeitpunkt seiner Erstellung. Sie können auf seine Elemente zugreifen, als wäre es die ursprüngliche Struktur, aber wenn Sie versuchen, sie zuzuweisen, werden Sie einen Fehler erzeugen.

z.

>> 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 

Es ist fast identisch in Syntax, mit Ausnahme der Ärger, dass Sie es mit () haben zu rufen. Ich habe es hier auf dem Terminal verwendet, aber offensichtlich kann es leicht auch im Kontext einer Funktion verwendet werden.

Kleiner Vorbehalt; Wenn Sie neu definieren und die anonyme Funktion überschreiben, führt dies natürlich zu Fehlzündungen, da es den neuen Arbeitsbereich übernimmt, auf den es zum Zeitpunkt der Neudefinition Zugriff hatte.

Lösung 2: Gut, wenn Sie Ihre Struktur des Formulars im Voraus:

Angenommen, Sie im Voraus wissen, dass Ihre Struktur a und b nur Felder enthalten. Erstellen Sie eine Klasse mit denselben Eigenschaften, die 'SetAccess' einschränken, z.

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 

dann in der Hauptcode:

>> 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 Ich aktualisiert mit einer eleganteren Lösung, vorausgesetzt, Sie wissen im Voraus die Form Ihrer Struktur. –

+0

Ich werde diese "Casting-to-Object" -Methode tatsächlich ausprobieren. Es scheint ziemlich nah an dem zu sein, wonach ich gesucht habe ... obwohl ich nicht die Idee mag, irgendwo ein "Spiegel" -Objekt zu definieren. – physmom

+0

Deshalb habe ich den gleichen Variablennamen verwendet, um die alte Struktur zu überschreiben. Eine gute Programmierpraxis warnt normalerweise vor der gleichen Variablen, die verschiedene Typen enthält, aber ich denke, dass Sie in diesem Fall eine Ausnahme machen können :) –

5

Sie sollten

  1. definieren die Variable in der Funktion persistent
  2. sperren Sie Ihre Funktion im Speicher mlock mit sein.

mlock sperrt die derzeit Funktion im Speicher ausgeführt wird, so dass nachfolgende clear Funktionen, die es nicht entfernen. Das Sperren einer Funktion im Speicher verhindert außerdem, dass in der Datei definierte permanente Variablen neu initialisiert werden.

+0

eine andere Lösung, wenn Sie zufrieden sind objektorientierten Code zu verwenden, Ihre Funktion eine Member-Funktion ist zu machen, die eine Eigenschaft mit dem „Konstante“ Attribut initialisiert –

+0

tatsächlich kommen, um darüber nachzudenken, ich denke, wir beide falsch interpretiert OP's Frage. Ich denke, dass sie nach dem Sperren der Variablen sind, während sie noch im ersten Durchlauf der Funktion sind. –

+0

Das ist gut zu wissen, +1, aber @ Tasos Papastylianou Antwort war näher an das, was ich suchte. Ich wusste nicht über 'mlock'! – physmom