我有一个关于 UML 数据类型的问题。
UML 上层结构说:
数据类型是其实例仅由其值标识的类型。
如果我理解正确,这意味着通过查看所有属性的值来检查相等性。
这是否也意味着 DataTypes 总是像 C# 结构一样被复制?
它们是否按值传递给方法,如果我将 DataType 分配给新变量,这是否会复制?(例如在阿尔夫)
我在互联网上找不到这个问题的答案。
我有一个关于 UML 数据类型的问题。
UML 上层结构说:
数据类型是其实例仅由其值标识的类型。
如果我理解正确,这意味着通过查看所有属性的值来检查相等性。
这是否也意味着 DataTypes 总是像 C# 结构一样被复制?
它们是否按值传递给方法,如果我将 DataType 分配给新变量,这是否会复制?(例如在阿尔夫)
我在互联网上找不到这个问题的答案。
这是一个很好的问题。通常情况下,基本 UML 规范中的语义描述有点模糊。然而,Alf 基于基础 UML (fUML) 语义,而 fUML 在这一点上是精确的。
简短的回答是,数据类型确实是按值传递的,而不是引用传递,并且是不可变的。任何对数据类型值的明显变异操作实际上都会导致创建一个新值。例如,考虑 Point 数据类型的以下 Alf 代码:
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 规范中,数据值与对象的语义没有模糊性。