名前と値の引数の検証
名前と値の引数は、関数に渡される値に名前を関連付けます。名前と値の引数には、次の特徴があります。
任意の順序で関数に渡すことができる
常にオプションである
すべての位置引数と繰り返し引数の後に宣言しなければならない
Repeating
属性を使用するarguments
ブロック内では使用できない名前と値の構造体を複数使用する場合でも、一意の名前を使用しなければならない
位置引数にも使用されている名前は使用できない
ドット表記を使用して arguments
ブロック内で名前と値の引数を宣言し、構造体のフィールドを定義します。たとえば、NameValueArgs
という名前の構造体は、2 つの名前と値の引数 Name1
および Name2
を定義します。任意の有効な MATLAB® 識別子を構造体名として使用できます。
arguments NameValueArgs.Name1 NameValueArgs.Name2 end
構造体名は関数シグネチャ内になければなりません。
function myFunction(NameValueArgs)
名前と値の構造体のフィールド名を使用して、関数を呼び出します。
myFunction(Name1=value1,Name2=value2)
R2021a より前は、string または文字ベクトルとして名前を渡し、名前と値をコンマで区切ります。両方の構文は以降のリリースでも有効です。
関数シグネチャ内で使用される構造体の名前は、関数に渡される名前と値を含む関数ワークスペース内の構造体の名前です。
function result = myFunction(NameValueArgs) arguments NameValueArgs.Name1 NameValueArgs.Name2 end % Function code result = NameValueArgs.Name1 * NameValueArgs.Name2; end
r = myFunction(Name1=3,Name2=7)
r = 21
あいまいさがない場合は、名前と値の引数は名前の部分一致をサポートします。たとえば、LineWidth
および LineStyle
を 2 つの名前と値の引数として定義する関数は、LineW
と LineS
を受け入れますが、Line
を使用するとエラーになります。一般に、コードの可読性を向上させ、予期しない動作を回避するために、完全名を使用することが推奨されます。
関数呼び出しで同じ名前と値の引数をエラーなしで繰り返すことができますが、指定される最新バージョンは MATLAB が受け入れるバージョンです。たとえば、以下の plot
の呼び出しでは、Color
の値が 2 回指定されています。MATLAB はプロットを赤色で表示します。
plot(x,y,Color="blue",LineStyle="--",Color="red")
名前と値の引数の既定値
それぞれの名前に既定値を指定できます。既定値を指定せずに、その名前と値の引数なしで関数が呼び出される場合、そのフィールドは名前と値の構造体に存在しません。名前と値の引数が関数に渡されない場合、MATLAB は構造体を作成しますが、そこにフィールドはありません。
関数呼び出しで渡された名前と値の引数を特定するには、関数 isfield
を使用します。
たとえば、次の関数は 2 つの必須の位置引数 (width
と height
) および 2 つの名前と値の引数 (LineStyle
と LineWidth
) を定義します。この例では、options
構造体には 2 つのフィールド (LineStyle
と LineWidth
) があり、既定値か、または関数の呼び出し時に名前と値の引数として指定された値が含まれています。
function myRectangle(width,height,options) arguments width double height double options.LineStyle (1,1) string = "-" options.LineWidth (1,1) {mustBeNumeric} = 1 end % Function code ... end
以下の構文はすべて、この関数を呼び出す有効な方法です。
myRectangle(4,5) myRectangle(4,5,LineStyle=":",LineWidth=2) myRectangle(4,5,LineWidth=2,LineStyle=":") myRectangle(4,5,LineStyle=":") myRectangle(4,5,LineWidth=2)
R2021a より前は、string または文字ベクトルとして名前を渡し、名前と値をコンマで区切ります。以下に例を示します。
myRectangle(4,5,"LineStyle",":","LineWidth",2) myRectangle(4,5,"LineWidth",2,"LineStyle",":")
繰り返し引数および名前と値の引数の使用
関数で繰り返し引数が定義されている場合、繰り返し arguments ブロックに続く別の arguments
ブロック内で名前と値の引数を宣言しなければなりません。たとえば、次の関数は 2 つの繰り返し引数 x
と y
を受け入れます。x
と y
の繰り返しをすべて指定した後に、値 lin
または log
を名前 PlotType
に代入する名前と値の引数を指定できます。
関数呼び出しに PlotType
引数が含まれるかどうかを判定するには、関数 isfield
を使用して scale
構造体の PlotType
フィールドをチェックします。
function myLinLog(x,y,scale) arguments(Repeating) x (1,:) double y (1,:) double end arguments scale.PlotType (1,1) string end z = reshape([x;y],1,[]); if isfield(scale,"PlotType") if scale.PlotType == "lin" plot(z{:}) elseif scale.PlotType =="log" loglog(z{:}) end end end
名前と値の引数を指定して、または指定せずに、この関数を呼び出します。
myLinLog(1:5,1:5)
myLinLog(1:5,1:5,1:10,1:100:1000)
myLinLog(1:5,1:5,1:10,1:100:1000,PlotType="log")
R2021a より前は、string または文字ベクトルとして名前を渡し、名前と値をコンマで区切ります。以下に例を示します。
myLinLog(1:5,1:5,1:10,1:100:1000,"PlotType","log")
複数の名前と値の構造体
関数の引数ブロックには、複数の名前と値の構造体を含めることができます。ただし、フィールド名は構造体全体で一意でなければなりません。以下の関数には、lineOptions
と fillOptions
という 2 つの名前と値の構造体があります。これらの構造体は同じフィールド名をもつことができません。
関数 myRectangle
の引数は次のとおりです。
width
とheight
はdouble
型の必須の位置引数である。lineOptions.LineStyle
は既定値"-"
をもつスカラー string である。lineOptions.LineWidth
は既定値1
をもつスカラー数値である。fillOptions.Color
は string である。fillOptions.Pattern
には値の制限がない。
function myRectangle(width,height,lineOptions,fillOptions) arguments width double height double lineOptions.LineStyle (1,1) string = "-" lineOptions.LineWidth (1,1) {mustBeNumeric} = 1 fillOptions.Color string fillOptions.Pattern end % Function Code ... end
名前と値の引数のロバストな処理
関数に名前と値の引数を実装するためのベスト プラクティスは、その引数を arguments ブロックで定義することです。arguments ブロックでは、名前と値の引数を解析するための独自コードを作成する必要がなく、"name",value
構文と R2021a で導入された name=value
構文の両方に対応するロバストな引数解析を実装できます。
有効な名前の適用
arguments ブロックで名前と値の引数を定義すると、名前が確実に有効な識別子になります。これにより、引数が "name",value
と name=value
の両方の構文で確実に機能するようになります。たとえば、無効な識別子を使用している名前と値の引数は、コンマ区切りの構文では機能できます。
myFunction(data,"allow-empty",true)
allow-empty=true
を使用した同じ呼び出しでは、エラーがスローされます。arguments ブロックで名前と値の引数を定義すると、定義した名前が確実に有効な MATLAB 変数名になり、name=value
構文に適合します。テキスト入力での予期しない結果の回避
オプションのテキスト入力および名前と値の引数の両方を含む関数では、MATLAB によってテキスト入力が名前と値の引数の名前として解釈されるおそれがあります。次の関数には、2 つのオプションのテキスト入力と 1 つの名前と値の引数が含まれています。
function mySignal(tag,unit,opts) arguments tag = "0" unit = "ampere" opts.Magnifier {mustBeMember(opts.Magnifier,["small","medium","big"])} end end
tag
の値を "Mag"
、unit
の値を "coulomb"
に設定するつもりで、次の関数呼び出しを入力します。mySignal("Mag","coulomb")
"Mag"
を名前と値の引数 Magnifer
として解析します。"coulomb"
はその名前に対して有効な値ではないため、この関数はエラーになります。これを回避する方法の 1 つとして、tag
の既定値を削除してそれを必須の引数にする方法があります。
function mySignal(tag,unit,opts) arguments tag unit = "ampere" opts.Magnifier {mustBeMember(opts.Magnifier,["small","medium","big"])} end end
tag
の値が "Mag"
に設定され、エラーは発生しません。もう 1 つの方法として、3 つすべての入力を名前と値の引数にする方法があります。これにより、各値が名前に関連付けられるため、ユーザーは入力を指定するときに誤りを回避でき、ユーザーが入力を指定する順序は最終結果に影響しません。
クラス プロパティからの名前と値の引数
MATLAB には、クラスのパブリック プロパティを名前と値の引数の名前に使用する便利な関数構文があります。クラスで定義されたすべての設定可能なプロパティ (つまり、パブリックの SetAccess
をもつすべてのプロパティ) に名前と値の引数を指定するには、arguments
ブロックで次の構文を使用します。
structName.?ClassName
関数は、"structName
.?
ClassName
" 構文を 1 回だけ使用できます。したがって、関数は、異なるクラスと構造体名を使用する場合でも、クラスからフィールド名を取得する名前と値の構造体は 1 つしか定義できません。
クラスでプロパティ検証を使用して、プロパティに代入できる値を制限している場合、関数はその検証を個々の名前と値の引数に適用します。プロパティ検証の詳細については、プロパティ値の検証を参照してください。
たとえば、次の関数は 2 つの必須の引数 x
と y
をもち、matlab.graphics.chart.primitive.Bar
クラスの任意のパブリック プロパティ名と値を受け入れます。
function myBar(x,y,propArgs) arguments x (:,:) double y (:,:) double propArgs.?matlab.graphics.chart.primitive.Bar end propertyCell = namedargs2cell(propArgs); bar(x,y,propertyCell{:}) end
必須の入力と、任意の設定可能なプロパティの名前と値のペアを指定して、関数を呼び出します。
x = [1,2,3;4,5,6]; y = x.^2; myBar(x,y) myBar(x,y,FaceColor="magenta",BarLayout="grouped")
R2021a より前は、string または文字ベクトルとして名前を渡し、名前と値をコンマで区切ります。以下に例を示します。
myBar(x,y,"FaceColor","magenta","BarLayout","grouped")
特定のプロパティのオーバーライド
arguments ブロック内で、プロパティ名を特定の名前と値の引数で再定義することにより、クラスのプロパティ検証をオーバーライドできます。
structName.?ClassName structName.PropertyName (dim1,dim2,...) ClassName {fcn1,fcn2,...}
特定の名前と値の引数の検証は、個別に指定されたプロパティ名に対しクラスで定義された検証をオーバーライドします。
たとえば、以下の関数は名前と値の引数を matlab.graphics.chart.primitive.Bar
クラスのプロパティとして定義します。また、この関数は、特定の値 red
または blue
のみが許可されるように、プロパティ名 FaceColor
をオーバーライドします。
matlab.graphics.chart.primitive.Bar
クラスでの FaceColor
の既定値は、制限された値 (red
または blue
) のいずれでもありません。したがって、オーバーライドする宣言では、検証関数 mustBeMember
によって課された制限を満たす既定値を代入しなければなりません。つまり、既定値は red
または blue
でなければなりません。
この関数は関数 namedargs2cell
を使用して、名前と値の構造体を、交互に配置された名前と値を含む cell 配列に変換します。
function myBar(x,y,propArgs) arguments x (:,:) double y (:,:) double propArgs.?matlab.graphics.chart.primitive.Bar propArgs.FaceColor {mustBeMember(propArgs.FaceColor,{'red','blue'})} = "blue" end propertyCell = namedargs2cell(propArgs); bar(x,y,propertyCell{:}) end
2 つの必須の引数 x
と y
を使用して関数を呼び出します。オプションで、関数 bar でサポートされる任意の名前と値のペアと、FaceColor
の値 (red
または blue
のいずれか) を渡します。FaceColor
の他の値は許可されません。
x = [1,2,3;4,5,6]; y = x.^2; myBar(x,y) myBar(x,y,FaceColor="red",BarLayout="grouped")