我有一个关于UML数据类型的问题。
UML上层建筑说:
数据类型是其实例仅由其值标识的类型。
如果我理解正确,这意味着通过查看所有属性的值来检查相等性。
这是否也意味着数据类型总是像 C# 结构一样被复制?
它们是否按值传递给方法,如果我将 DataType 分配给新变量,这会生成副本吗?(例如在阿尔夫中)
我在互联网上找不到这个问题的答案。
这是一个很好的问题。通常情况下,基本 UML 规范中的语义描述有点模糊。然而,Alf是基于基础UML(fUML)语义的,而fUML在这一点上是精确的。
简短的回答是,数据类型实际上是按值传递的,而不是按引用传递的,并且是不可变的。对数据类型的值进行的任何明显变异操作实际上都会导致创建新值。例如,请考虑以下 Alf 代码作为 Point 数据类型:
a = new Point(1,1);
b = a;
a.x = 2;
赋值b = a;
实际复制点数据值。因此,分配a.x = 2;
对b
没有影响。确实,这第二个作业实际上相当于a = new Point(2, a.y);
。也就是说,它会导致创建一个新的点数据值,然后将其重新分配给a
。
这些语义在 Alf 和 fUML 规范中明确涵盖。数据类型的定义在 Alf 规范 1 的子条款 10.4.4 中介绍。但是,上述赋值的语义在子条款 8.8 中,其中说,在对属性引用的简单赋值的描述下(如a.x
):
如果属性引用具有局部的主表达式 名称或参数名称,并且具有结构化数据类型的类型, 然后,对属性引用的赋值有效地分配了一个 该本地或参数名称的新数据值,具有给定的 属性已更新。
如果您对数据值语义的更多详细信息感兴趣,可以在 fUML 规范 2 中找到此信息。值的语义在子条款 8.3.2.1 中讨论。关键是数据值和"扩展值"之间存在区别。扩展值存在于其分类器的范围中,与它们的使用无关 - 这在 fUML 中等效于运行时实现概念的"堆"。
扩展值包括链接(作为关联的实例)和对象(作为类的实例)。此外,还有用于引用对象的参考值。它总是对传递的对象引用,而不是对象本身 - 对象只是存在于执行轨迹("在堆上")。因此,对象具有引用语义,而不是数据值,数据值本身可以作为值传递。
因此,在fUML规范中,数据值与对象的语义没有歧义。
UML数据类型或多或少等于不可变对象的概念:无法更改的对象。
这确实也很像 C# 中的值类型,除了字符串之类的东西,它们实际上是不可变的引用类型。因此,字符串也将被视为 UML 数据类型。