структурная эквивалентность против эквивалентности имени - PullRequest
13 голосов
/ 20 декабря 2010

Я не могу понять, что такое эквивалентность имени.Я почти уверен, что у меня есть структурный недостаток.Мой профессор привел следующий пример:

 Type TI=integer
 Type TTI=TI

 a=integer
 b=TTI
 f= ref float
 g= ref float

a и b являются как структурными, так и именными эквивалентами, в то время как f и g являются просто структурными эквивалентами. Я не понимаю, почему a и b будут эквивалентны именамно f и g - нет.

Ответы [ 5 ]

32 голосов
/ 08 июля 2015

Тип Равенство

Значение основных операций, таких как присваивание (обозначается = в C), указывается в определении языка. Так, например, значение таких утверждений, как

x = y;

здесь значение объекта y копируется в ячейки памяти для переменной 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 и y будут одного типа, а r и s будут того же типа, но тип x или y не будут эквивалентны типу r или s. Это означает, что такие заявления, как

   x = y;
   r = s;

будет допустимым, но такие утверждения, как

   x = r;

не будет действительным (т.е. не будет принято переводчиком).

Использование структурной эквивалентности: , два типа равны тогда и только тогда, когда они имеют одинаковую "структуру" , что можно интерпретировать по-разному.
Строгое толкование состоит в том, что имена и типы каждого компонента двух типов должны быть одинаковыми и должны быть перечислены в том же порядке в определении типа.
Менее строгим требованием будет то, что типы компонентов должны быть одинаковыми и в одинаковом порядке в обоих типах, но имена компонентов могут отличаться.

Снова рассмотрев приведенный выше пример, используя структурную эквивалентность , два типа Stack и Set будут считаться эквивалентными, что означает, что переводчик будет принимать такие выражения, как

x = r;

(Обратите внимание, что C не поддерживает структурную эквивалентность и выдаст ошибку для указанного выше назначения.)

4 голосов
/ 02 ноября 2013

Рассмотрим два нижеприведенных определения.

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. Эквивалентность имени основана на предположении, что если программист приложит усилия для написания двух определений типов, то эти определения, вероятно, должны представлять разные типы.(Я не уверен в приведенном вами примере)

Ссылка: Прагматика языков программирования, М. Л. Скотт

3 голосов
/ 03 июня 2011

Понятие эквивалентности имен наиболее целесообразно, если учесть внутренние структуры данных, которые компилятор может использовать для представления типов. Предположим, что типы представлены в виде указателей на структуры данных. Кроме того, предположим, что я реализую проверку эквивалентности типов как простое сравнение указателей (например, эквивалентность имени). Примитивные типы, такие как integer и float, будут храниться в некоторой глобальной среде, поскольку их существует только конечное число. Кроме того, если я сравню integer с integer, они гарантированно будут эквивалентны, поскольку они указывают на одну и ту же структуру в силу этой глобальной среды.

Однако, поскольку ref не является конструктором типа , а не атомарным типом, я могу использовать его для создания бесконечного числа типов (например, ref float, ref ref float и т. Д.). Поэтому мы не можем хранить их все в глобальной среде. Одна из простых стратегий, которую компилятор может использовать для управления этими типами, - это выделение новой структуры всякий раз, когда мы сталкиваемся с конструктором типов, мы выделяем новую структуру данных для этого типа. Таким образом, экземпляр ref float приведет к одной новой структуре данных, а другой экземпляр ref float приведет к совершенно новой, другой структуре данных. Сбой сравнения указателей, и поэтому они не могут быть эквивалентными по имени.

Есть еще одна часть головоломки, которая заключается в семантике вашего оператора присваивания. Этот псевдоним типа является простой копией указателя в компиляторе, поэтому, если я пишу A=B, A всегда по имени эквивалентно B. Но, повторюсь, F A не является именем, эквивалентным другому экземпляру F A!

2 голосов
/ 31 января 2011

a и b являются союзниками, поэтому они эквивалентны именам.f и g не так, они не эквивалентны именам.

1 голос
/ 02 февраля 2015

В эквивалентности типа имени две переменные имеют одинаковый тип, если они определены в одном и том же объявлении или в объявлениях, использующих одно и то же имя типа. Следовательно, переменные 'f' и 'g' в вашем примере являются эквивалентами. Однако переменные 'a' и 'b' не являются эквивалентами, поскольку они имеют разные имена типов. Кроме того, при эквивалентности структурного типа две переменные имеют одинаковый тип, если имеют одинаковую структуру. Таким образом, переменные 'a' и 'b' являются эквивалентами, а также переменные 'f' и 'g' являются эквивалентами, поскольку, очевидно, типы с одинаковыми именами имеют одинаковую структуру.

Ссылка: Sebesta, Концепции языков программирования, 10-е изд.

...