我似乎无法准确掌握名称等效性是什么。我很确定我的结构已经下降。我的教授举的一个例子是这样的:
Type TI=integer
Type TTI=TI
a=integer
b=TTI
f= ref float
g= ref float
a 和 b 都是结构和名称等价的,而 f 和 g 只是结构等价的。我不明白为什么 a 和 b 名称等价,但 f 和 g 不是。
我似乎无法准确掌握名称等效性是什么。我很确定我的结构已经下降。我的教授举的一个例子是这样的:
Type TI=integer
Type TTI=TI
a=integer
b=TTI
f= ref float
g= ref float
a 和 b 都是结构和名称等价的,而 f 和 g 只是结构等价的。我不明白为什么 a 和 b 名称等价,但 f 和 g 不是。
类型平等
诸如赋值之类的基本操作的含义(在 C 中用 = 表示)在语言定义中指定。因此,例如,语句的含义,例如
x = y;
这里 object 的值y
被复制到 variable 的内存位置x
。
但是,在翻译器可以接受诸如赋值之类的操作之前,通常两个操作数的类型必须相同(或者可能以其他指定的方式兼容)。
因此,语言翻译者必须决定在某些情况下两种类型是否相等。我们现在考虑说两种类型“相等”(或等价)是什么意思。
有两种标准方法可以确定两种类型是否相同: 名称等价和结构等价。
名称等价是最直接的:当且仅当它们具有相同的名称时,两种类型才相等。因此,例如,在代码中(使用 C 语法)
typedef struct {
int data[100];
int count;
} Stack;
typedef struct {
int data[100];
int count;
} Set;
Stack x, y;
Set r, s;
如果在语言中使用名称等价,则x
andy
将属于同一类型,并且r
ands
将属于同一类型,但x
or的类型y
不等同于r
or的类型s
。这意味着诸如
x = y;
r = s;
将是有效的,但诸如
x = r;
将无效(即,不会被翻译人员接受)。
使用结构等价:,当且仅当它们具有相同的“结构”时,两种类型才相等,可以用不同的方式解释。
严格的解释是这两种类型的每个组件的名称和类型必须相同,并且必须在类型定义中以相同的顺序列出。
一个不太严格的要求是组件类型必须相同并且在两种类型中的顺序相同,但组件的名称可以不同。
再看上面的例子,使用结构等价这两种类型Stack
,并且Set
会被认为是等价的,这意味着翻译者会接受如下语句
x = r;
(请注意,C
它不支持结构等价,并且会为上述分配出错。)
考虑下面的两个定义。
type student = record
name, address : string
age : integer
type school = record
name, address : string
age : integer
x : student;
y : school;
在上面的示例中,变量 x 和 y 在名称等价下将被认为具有不同的类型: x 使用在第 1 行声明的类型;y 使用在第 4 行声明的类型。名称等价是基于这样的假设:如果程序员努力编写两个类型定义,那么这些定义可能意味着表示不同的类型。(我不确定你给出的例子)
参考:Programming Languages Pragmatics,作者:ML Scott
如果您考虑编译器可能用来表示类型的内部数据结构,那么名称等效的概念最有意义。假设类型被表示为指向数据结构的指针。此外,假设我将类型等价检查实现为简单的指针比较(例如名称等价)。原始类型喜欢integer
并且float
将存储在某些全局环境中,因为它们的数量是有限的。此外,如果我与 进行比较integer
,integer
则可以保证它们是等价的,因为由于这种全局环境,它们指向相同的结构。
但是,由于ref
不是类型构造函数,也不是原子类型,因此我可以使用它来创建无限多种类型(例如ref float
,ref ref float
等)。所以我们不能将它们全部存储在全局环境中。编译器可以用来管理这些类型的一种简单策略是,每当遇到类型构造函数时分配一个新结构,我们为该类型分配一个新数据结构。因此, 的实例ref float
将产生一个新的数据结构,而另一个实例ref float
将产生一个全新的、不同的数据结构。指针比较失败,因此它们不能是名称等效的。
还有一个难题,那就是赋值运算符的语义。这种类型别名是编译器中的简单指针副本,所以如果我写A=B
,A
总是名称等同于B
. 但是,重申一下,F A
它的名称不等同于 ! 的另一个实例F A
。
在名称类型等价中,如果两个变量在同一个声明中或在使用相同类型名称的声明中定义,则它们具有相同的类型。因此,变量'f'
和'g'
在您的示例中是等价的。但是,变量'a'
和'b'
不是等价物,因为它们具有不同的类型名称。此外,在结构类型等价下,如果两个变量具有相同的结构,则它们具有相同的类型。因此,变量'a'
和'b'
是等价的,变量'f'
和'g'
也是等价的,因为很明显,具有相同名称的类型具有相同的结构。
参考:Sebesta,编程语言概念,第 10 版。
a 和 b 是别名,这就是它们同名的原因。f 和 g 不是,所以它们不是名称等价的。
别名:多个名称引用同一个对象(即同一个内存位置可以使用不同的名称访问)
a 和 b 是别名,而 f 和 g 指的是恰好都是“ref float”的不同对象