验证属性值
类定义中的属性验证
MATLAB® 属性验证使您能够对属性值进行特定限制。您可以使用验证来约束属性值的类和大小。此外,您可以使用函数来建立属性值必须符合的条件。MATLAB 定义了一组验证函数,您也可以编写自己的验证函数。
在类定义中,属性验证的使用是可选的。
关于属性验证的其他信息
有关属性验证的详细信息,请参阅Property Class and Size Validation、属性验证函数和Metadata Interface to Property Validation。
验证语法
下面代码中突出显示的区域显示属性验证的语法。
属性验证包括以下任一项:
大小 - 每个维度的长度,指定为正整数或冒号。冒号表示该维度中允许任何长度。赋给属性的值必须符合指定的大小或与指定的大小兼容。有关详细信息,请参阅Property Size Validation。
类 - 单个 MATLAB 类的名称。赋给属性的值必须属于指定的类或可转换为指定的类。使用 MATLAB 类或 MATLAB 支持的任何外部定义的类,但 Java® 和 COM 类除外。有关详细信息,请参阅Property Class Validation。
函数 - 以逗号分隔的验证函数名称列表。MATLAB 在应用任何可能的类和大小转换后,将赋给属性的值传递给每个验证函数。如果验证失败,验证函数会引发错误,但不会返回值。有关详细信息,请参阅属性验证函数。
有关 MATLAB 验证函数的列表,请参阅属性验证函数。
使用属性验证
使用公共属性的属性验证来控制用户代码赋给属性的值。
如果要将属性值限制为一组固定的标识符,请创建包含这些标识符的枚举类,并将属性值范围限制为该类。有关枚举类的信息,请参阅定义枚举类。
MATLAB 类型转换规则适用于属性验证。例如,MATLAB 可以对数值类型进行强制转换。因此,将属性值限制为特定的数值类型(如双精度)不会阻止使用其他数值类型对属性赋值。
要确保只能将特定类型的值赋给属性,请将属性限制为仅支持所需类型转换的类型,或者使用验证函数指定属性允许的确切类,而不是指定属性类型。MATLAB 在执行任何验证函数之前先计算类型设定。有关详细信息,请参阅验证的顺序。
指定有效默认值
确保赋给属性的默认值满足指定验证所施加的限制。如果未指定默认值,MATLAB 会使用指定类的空对象进行赋值来创建默认值;如果大小限制不允许使用空默认值,则调用默认构造函数来创建默认值。默认构造函数必须返回正确大小的对象。
使用属性验证的示例类
ValidateProps
类定义三个属性并进行验证。
classdef ValidateProps properties Location(1,3) double {mustBeReal, mustBeFinite} Label(1,:) char {mustBeMember(Label,{'High','Medium','Low'})} = 'Low' State(1,1) matlab.lang.OnOffSwitchState end end
Location
必须为double
类的 1×3 数组,其值是有限实数。Label
必须为char
向量,包含'High'
、'Medium'
或'Low'
之一。State
必须为matlab.lang.OnOffSwitchState
类的枚举成员(off
或on
)。
实例化时的验证
创建 ValidateProps
类的对象会对隐式和显式默认值执行验证:
a = ValidateProps
a = ValidateProps with properties: Location: [0 0 0] Label: 'Low' State: off
在创建对象时,MATLAB 会:
将
Location
属性值初始化为[0 0 0]
,以满足大小和类要求。将
Label
属性设置为默认值'Low'
。默认值必须为允许的值集的成员。空的char
隐式默认值会导致错误。将
State
属性设置为matlab.lang.OnOffSwitchState
类定义的off
枚举成员。
有关 MATLAB 如何选择默认值的信息,请参阅Default Values Per Size and Class。
验证的顺序
对属性赋值(包括类定义中指定的默认值)时,MATLAB 会按以下顺序执行验证:
类验证 - 此验证可导致转换为不同类,例如将
char
转换为string
。属性赋值遵循 MATLAB 对数组的转换规则。大小验证 - 此验证可导致大小转换,例如标量扩展或列向量到行向量的转换。对指定大小验证的属性进行赋值时,其行为与 MATLAB 数组的赋值行为相同。有关索引赋值的信息,请参阅数组索引。
验证函数 - MATLAB 按照从左到右的顺序将类验证和大小验证的结果传递给每个验证函数。在调用完所有验证函数之前可能会发生错误,从而结束验证过程。
set 方法 - MATLAB 在调用属性 set 方法(如果为属性定义了该方法)之前执行属性验证。通过属性 set 或 get 方法为属性赋值时不会再次应用验证。通常,您可以使用属性验证来替换属性 set 方法。
属性验证错误
ValueProp
类使用大小、类和函数验证来确保对 Value
属性的赋值是非负的双精度标量。
classdef ValueProp properties Value(1,1) double {mustBeNonnegative} = 0 end end
以下语句尝试将元胞数组赋给属性。此赋值违反类验证。
a.Value = {10,20};
Error setting property 'Value' of class 'ValueProp': Invalid data type. Value must be double or be convertible to double.
以下语句尝试将 1×2 双精度数组赋给属性。此赋值违反大小验证。
a.Value = [10 20];
Error setting property 'Value' of class 'ValueProp': Size of value must be scalar.
以下语句尝试将双精度标量赋给属性。此赋值未通过函数验证,该验证要求使用非负数。
a.Value = -10;
Error setting property 'Value' of class 'ValueProp': Value must be nonnegative.
验证过程在遇到第一个错误时结束。
抽象属性验证
您可以为抽象属性定义属性验证。验证会应用于实现该属性的所有子类。但是,子类无法对其自身属性的实现使用任何验证。从多个类继承属性验证时,只有一个超类中的单一 Abstract 属性可以定义验证。任何超类都不能将属性定义为具体属性。
更改验证时不更新对象
如果在类的对象存在时更改属性验证,MATLAB 不会尝试将新验证应用于现有属性值。只有在您对现有对象的属性进行赋值时,MATLAB 才会应用新验证。
加载操作期间的验证
将对象保存到 MAT
文件时,MATLAB 会将所有非默认属性值与对象一起保存。在加载对象时,MATLAB 会在新创建的对象中还原这些属性值。
如果类定义更改了属性验证,使得加载的属性值不再有效,则 MATLAB 会将其值替换为当前定义的该属性的默认值。但是,在将当前类定义的默认值赋给属性之前,load
函数会阻止验证错误的显示。因此,在加载操作期间,验证错误会以静默方式被忽略。
为了说明此行为,以下示例创建、保存并加载了 MonthTemp
类的一个对象。此类将 AveTemp
属性限制为元胞数组。
classdef MonthTemp properties AveTemp cell end end
创建一个 MonthTemp
对象,并为 AveTemp
属性赋值。
a = MonthTemp;
a.AveTemp = {'May',70};
使用 save
保存对象。
save TemperatureFile a
编辑属性定义,以将 AveTemp
属性的验证类从元胞数组更改为 containers.Map
。
classdef MonthTemp properties AveTemp containers.Map end end
在 MATLAB 路径上加载具有新类定义的已保存对象。MATLAB 无法将保存的值赋给 AveTemp
属性,因为元胞数组 {'May',70}
与当前要求属性值为 containers.Map
的对象不兼容。MATLAB 无法将元胞数组转换为 containers.Map
。
为了解决不兼容问题,MATLAB 将所加载对象的 AveTemp
属性设置为当前默认值,即空的 containers.Map
对象。
load TemperatureFile a a.AveTemp ans = Map with properties: Count: 0 KeyType: char ValueType: any
现在系统为所加载对象的 AveTemp
属性赋了一个不同的值,因为保存的值现在无效。但是,加载过程会抑制验证错误的显示。
为了防止在更改类定义和重新加载对象时缺失数据,请实现 loadobj
方法或类转换器方法,使保存的值满足当前属性验证。
有关保存和加载对象的详细信息,请参阅对象的保存和加载过程。