如何声明接收名称-值参数的构造函数定义MATLAB不可变属性?
MATLAB不可变属性类的优雅名称-值参数构造方案
自MATLAB R2019b起,我们可以用props.?C语法快速将类的可设置属性绑定为构造函数的名称-值参数,无需在代码中逐个声明属性,写法非常简洁。但当属性设置为SetAccess = immutable时,这个语法会直接报错——因为它仅支持公共可设置属性,此时如果逐个显式声明参数,属性多了会导致代码冗余难维护。
这里提供两种无需重复声明属性的优雅实现方式:
方式一:通过类元数据动态处理参数
利用MATLAB的元类(meta.class)获取所有不可变属性,遍历传入的名称-值对直接在构造函数内赋值(构造函数是唯一能修改不可变属性的地方):
classdef C < handle & matlab.mixin.SetGet properties (SetAccess = immutable) Prop AnotherImmutableProp end methods function obj = C(varargin) arguments varargin{:} end % 将传入的参数转为结构体,方便处理 inputProps = struct(varargin{:}); % 获取当前类的元数据 classMeta = ?C; % 筛选出所有不可变属性的名称 validPropNames = {classMeta.Properties(... strcmp({classMeta.Properties.SetAccess.Name}, 'immutable')... ).Name}; % 校验传入的属性是否合法 invalidProps = setdiff(fieldnames(inputProps), validPropNames); if ~isempty(invalidProps) error('无效的属性参数: %s', strjoin(invalidProps, ', ')); end % 批量给不可变属性赋值 for propName = fieldnames(inputProps)' obj.(propName{1}) = inputProps.(propName{1}); end end end end
实例化测试:
>> C(Prop=123, AnotherImmutableProp='hello') ans = C with properties: Prop: 123 AnotherImmutableProp: 'hello'
方式二:简化版动态赋值(无参数校验)
如果不需要严格的参数校验,也可以直接遍历传入的参数对赋值,适合快速实现:
classdef C < handle & matlab.mixin.SetGet properties (SetAccess = immutable) Prop AnotherProp end methods function obj = C(varargin) arguments varargin{:} end % 遍历名称-值对直接赋值 for i = 1:2:length(varargin) propName = varargin{i}; obj.(propName) = varargin{i+1}; end end end end
这种写法更简洁,但缺少参数合法性校验,若传入不存在的属性会直接抛出MATLAB原生的属性不存在错误。
两种方式都能避免属性增多时重复修改构造函数的参数声明,保持代码的可维护性。
内容的提问来源于stack exchange,提问作者Will
相关产品推荐
相关产品推荐

