我可以声明一个接受名称-值参数的构造函数来定义不可变属性吗?

huangapple go评论66阅读模式
英文:

Can I declare a constructor that accepts Name-Value arguments to define immutable properties?

问题

Since MATLAB R2019b, it has been possible to declare name-value arguments from class properties, which provides an elegant way to define a class that can be constructed with property declarations without repeating each defined property in the constructor code:

classdef C < handle & matlab.mixin.SetGet
    properties
        Prop
    end
    
    methods
        function obj = C(props)
            arguments
                props.Prop = 1
            end
            obj.Prop = props.Prop;
        end
    end
end

You can then instantiate it like this:

>> C(Prop = 1)

ans =

  C with properties:
  
    Prop: 1

If you need the properties to be immutable, it's less clear how to do this neatly because the .? syntax supports only public settable properties. One approach is to declare props.Prop as a name-value constructor argument and assign each property one-by-one to the object, but this can become less maintainable as the number of class properties increases.

英文:

Since MATLAB R2019b it has been possible to declare name-value arguments from class properties which has created an elegant way to define a class that can be constructed with a declaration of its properties without repeating each defined property in the code for the constructor:

classdef C &lt; handle &amp; matlab.mixin.SetGet
    properties
       Prop
    end
    
    methods
        function obj = C(props)
            arguments
                props.?C
            end
            set(obj,props)
        end
    end
end

Which than can then be instantiated thus:

&gt;&gt; C(Prop = 1)

ans =

  C with properties:
  
    Prop: 1

If instead I need the properties to be immutable, it becomes less clear how to neatly do this. Simply changing properties to properties (SetAccess = immutable) is no good, because the .? syntax only seems to support public settable properties, so attempts to instantiate then result in the error:

Error using C
Invalid argument list. Function &#39;C constructor&#39; does not accept input arguments because class &#39;C&#39; referenced in the arguments block does not have public settable properties.

In this case, one could explicitly declare props.Prop as a name-value constructor argument instead, and assign each property one-by-one to the object, but this code coupling becomes more bloated and unmaintainable as the class properties become more numerous.

Is there a more direct way?

答案1

得分: 1

对于没有其他重复参数的类构造函数,可以通过定义重复参数并使用动态下标分配的方式复制名称-值参数模式:

classdef C < handle
    properties (SetAccess = immutable)
        Prop
    end

    methods
        function obj = C(name, value)
            arguments (Repeating)
                name (1, 1) string
                value
            end

            for ii = 1:numel(name)
                obj.(name{ii}) = value{ii};
            end
        end
    end
end

与将参数分配给 struct 的公共可设置属性的 .? 语法不同,这不能与构造函数的其他重复参数结合使用,因此不允许具有灵活函数签名,但在许多情况下填补了似乎存在的空白。

英文:

For classes with no other repeating arguments to the constructor, the Name-Value argument pattern can be replicated by defining repeating arguments and the values assigned using dynamic subscripting:

classdef C &lt; handle
    properties (SetAccess = immutable)
       Prop
    end
    
    methods
        function obj = C(name,value)
            arguments (Repeating)
                name (1,1) string
                value
            end

            for ii = 1:numel(name)
                obj.(name{ii}) = value{ii};
            end
        end
    end
end

Unlike the .? syntax with public-settable properties that assigns arguments to a struct, this can't be combined with other repeating arguments to the constructor, so doesn't allow for as flexible a function signature but will fill what seems otherwise to be a gap in many cases.

huangapple
  • 本文由 发表于 2023年7月4日 21:15:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613038.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定