Main Content

条件付きステートメント内のオブジェクト

条件付きステートメントでのオブジェクトの使用を有効にする

オブジェクトのクラスの関係演算子を定義して、条件付きステートメントでのオブジェクトの使用を有効にします。handle クラスから派生するクラスは関係演算子を継承します。値クラスは、オブジェクトを含む条件付きステートメントの使用をサポートする演算子を実装できます。クラスの演算子を定義する方法の詳細については、演算子のオーバーロードを参照してください。

MATLAB による switch ステートメントの評価方法

MATLAB® では、オブジェクトのクラスで eq メソッドが定義されている場合に、switch ステートメントでオブジェクトを使用できます。eq メソッドでは、そのクラスのオブジェクトで == 演算を実装します。

オブジェクトに対し、case_expression == switch_expression は MATLAB による switch/cases ステートメントの評価の方法を定義します。

eq メソッドによって返される値は logical 型であるか、または logical 型に変換可能でなければなりません。eq メソッドの出力が logical 以外の値の場合、MATLAB は eq の出力を logical 値に変換しようとします。

メモ

列挙クラスに eq メソッドを定義する必要はありません。switch ステートメント内の列挙型を参照してください。

Switch ステートメント内でのハンドル オブジェクト

handle クラスから派生したすべてのクラスは eq メソッドを継承します。たとえば、次の式について考えてみます。

h1 == h2

h1h2 が同じオブジェクトに対するハンドルの場合、この式は true になります。

たとえば、BasicHandle クラスは handle から派生します。

classdef BasicHandle < handle
   properties
      Prop1
   end
   methods
      function obj = BasicHandle(val)
         if nargin > 0
            obj.Prop1 = val;
         end
      end
   end
end

BasicHandle オブジェクトを作成し、switch ステートメント内で使用します。

h1 = BasicHandle('Handle Object');
h2 = h1;

switch ステートメント コードは以下のようになります。

switch h1
   case h2
      disp('h2 is selected')
   otherwise 
      disp('h2 not selected')
end

結果は次のようになります。

h2 is selected

オブジェクトはスカラー

switch ステートメントで使用できるオブジェクトはスカラー オブジェクトのみです。以下に例を示します。

h1(1) = BasicHandle('Handle Object');
h1(2) = BasicHandle('Handle Object');
h1(3) = BasicHandle('Handle Object');
h2 = h1;
switch h1
   case h2
      disp('h2 is selected')
   otherwise 
      disp('h2 not selected')
end

結果はエラー メッセージになります。

SWITCH expression must be a scalar or string constant.

この例では、h1 はスカラーではありません。switch ステートメントを開始する前に、isscalar を使用すると、オブジェクトがスカラーであるかどうかを調べることができます。

eq メソッドの定義方法

switch ステートメント内で値クラス オブジェクトを使用できるようにするには、クラスに eq メソッドを実装します。eq メソッドを使用して、2 つのクラス オブジェクトが等価となるための条件を指定します。

組み込みタイプのような動作

一部の MATLAB 関数は、関数の実装内で組み込みの == 演算子も使用します。そのため、クラス オブジェクトが MATLAB コード内で組み込みタイプと同じように機能するように、eq は組み込みの eq と置き換えられるように実装します。

eq の設計

eq メソッドを実装して == 比較の結果を表す logical 配列を返すようにします。

たとえば、SwitchOnVer クラスで eq メソッドを実装すると、2 つのオブジェクトで Version プロパティの値が同じである場合に、== 演算に対して true を返します。また、eq は組み込みの eq と同じように配列に対しても使用できます。以下の式について考えます。

obj1 == obj2

eq メソッドは次のように機能します。

  • obj1obj2 の両方がスカラーの場合は、eq でスカラー値が返されます。

  • obj1obj2 の両方が非スカラー配列の場合、これらの配列は同じ次元をもつ必要があり、eq では同じサイズの配列が返されます。

  • 1 つの入力引数がスカラーでもう 1 つの入力引数が非スカラー配列の場合、eq では、スカラーオブジェクトが非スカラー配列と同じ次元をもつ配列であるかのように扱われます。

eq の実装

次に、eq メソッドを実装するクラスを示します。目的の用途に対して適切なエラー チェックを確実に行うように実装してください。

classdef SwitchOnVer
   properties
      Version
   end
   methods
      function obj = SwitchOnVer(ver)
         if nargin > 0
            obj.Version = ver;
         end
      end
      function bol = eq(obj1,obj2)
         if ~strcmp(class(obj1),class(obj2))
            error('Objects are not of the same class')
         end
         s1 = numel(obj1);
         s2 = numel(obj2);
         if s1 == s2
            bol = false(size(obj1));
            for k=1:s1
               if obj1(k).Version == obj2(k).Version
                  bol(k) = true;
               else
                  bol(k) = false;
               end
            end
         elseif s1 == 1
            bol = scalarExpEq(obj2,obj1);
         elseif s2 == 1
            bol = scalarExpEq(obj1,obj2);
         else
            error('Dimension missmatch')
         end
         function ret = scalarExpEq(ns,s)
            % ns is nonscalar array
            % s is scalar array
            ret = false(size(ns));
            n = numel(ns);
            for kk=1:n
               if ns(kk).Version == s.Version
                  ret(kk) = true;
               else
                  ret(kk) = false;
               end
            end
         end
      end
   end
end

switch ステートメント内で SwitchOnVer オブジェクトを使用します。

% Create known versions of objects
ov1 = SwitchOnVer(1.0);
ov2 = SwitchOnVer(2.0);
ov3 = SwitchOnVer(3.0);
...

...
if isscalar(objIn)
      switch(objIn)
         case ov1
            disp('This is version 1.0')
         case ov2
            disp('This is version 2.0')
         case ov3
            disp('This is version 3.0')
         otherwise
            disp('There is no version')
      end
   else
      error('Input object must be scalar')
   end

switch ステートメント内の列挙型

MATLAB では、列挙クラスに対し明示的に定義された eq メソッドを要求せずに、switch ステートメントで列挙を使用できます。

たとえば、WeeklyPlanner クラスは週の 5 日の列挙型を定義します。静的メソッド todayScheduleswitch/case ステートメントは、現在の曜日に対応する列挙メンバーにディスパッチします。関数 datetimedaystring は、現在の曜日の名前をもつ文字列を返します。

classdef WeeklyPlanner
   enumeration
      Monday, Tuesday, Wednesday, Thursday, Friday
   end
   methods (Static)
      function todaySchedule
         dayName = string(day(datetime("name"));
         dayEnum =  WeeklyPlanner.(dayName);
         switch dayEnum
            case WeeklyPlanner.Monday
               disp("Monday schedule")
            case WeeklyPlanner.Tuesday
               disp("Tuesday schedule")
            case WeeklyPlanner.Wednesday
               disp("Wednesday schedule")
            case WeeklyPlanner.Thursday
               disp("Thursday schedule")
            case WeeklyPlanner.Friday
               disp("Friday schedule")
         end
      end
   end
end

todaySchedule を呼び出し、今日のスケジュールを表示します。

WeeklyPlanner.todaySchedule

組み込み型から派生した列挙型

組み込み型から派生した列挙クラスは、スーパークラスの eq メソッドを継承します。たとえば、FlowRate クラスは int32 から派生します。

classdef FlowRate < int32
   enumeration
      Low    (10)
      Medium (50)
      High   (100)
   end
end

関数 switchEnum は入力引数をオンにします。入力引数は FlowRate の列挙値をとります。

function switchEnum(inpt)
   switch inpt
      case 10
         disp('Flow = 10 cfm')
      case 50
         disp('Flow = 50 cfm')
      case 100
         disp('Flow = 100 cfm')
   end
end

列挙値を使用して switchEnum を呼び出します。

switchEnum(FlowRate.Medium)
Flow = 50 cfm