Несоответствие типов - PullRequest
       8

Несоответствие типов

2 голосов
/ 17 декабря 2011

Delphi.

Почему

type 
  myInt = Integer;
  myNewInt = -2147483648..2147483647;

var 
  a: myint;
  b: myNewInt;

begin
  a := b;
end;

Компилируется нормально, хотя типы формально разные - один объявлен здесь, другой берется из другого модуля.И если

uses 
  windows;

type
   _FILETIMEA = record // Copy from windows.pas
     dwLowDateTime: DWORD;
     dwHighDateTime: DWORD;
   end;

var 
  x: _FILETIMEA;
  y: windows._FILETIME;

begin
  x := y;
end;

вызовет ошибку компиляции (в строке x:=y; [DCC Error] ... E2010 Incompatible types: 'windows._FILETIME' and '_FILETIMEA'), хотя type _FILETIMEA = Windows._FILETIME?

Ответы [ 2 ]

9 голосов
/ 17 декабря 2011

Delphi не поддерживает утку.У вас есть 2 разные записи.Они просто похожи, но это два разных типа для компилятора.Если вы хотите назначить две переменные, вы должны набрать их, что возможно, потому что они имеют одинаковый размер.

x := _FILETIMEA(y);
7 голосов
/ 17 декабря 2011

Потому что вы не делаете то же самое.:) Delphi строго типизирован (исключений не так много - почти все имеют определенный тип).

type 
  myInt = Integer;
  myNewInt = -2147483648..2147483647;

В этих типах нет ничего несовместимого.Они оба имеют одинаковый тип (целое число) и поддерживают одинаковый диапазон значений.Нет никакого конфликта в разрешении присваивания одного другому.

// Your unit name
unit GuTypes;

Type
 _FILETIMEA = record // Copy from windows.pas
   dwLowDateTime: DWORD;
   dwHighDateTime: DWORD;
 end;

Это новый тип, определенный вашим кодом (даже если он идентичен типу в Windows.pas, это не то же самое),Это GuTypes._FileTimeA, что не то же самое, что Windows._FileTimeA.

Это на самом деле хорошо, потому что позволяет разным юнитам использовать одни и те же имена без конфликтов;Вы можете добавить префикс к имени устройства в качестве «пространства имен», чтобы уточнить, какое из них вы хотите использовать.Например, если ваше значение определено в GuTypes, а в Windows объявлен один, в третьем блоке MyAppCode, вы можете сделать это безопасно:

var
  GFileTime: GuTypes._FILETIMEA;
  WFileTime: Windows._FILETIMEA;

Даже если один изИзменения типов, ваш код защищен от побочных эффектов, потому что эти два типа не могут случайно поменяться местами.

Вы можете настроить тип, чтобы заставить назначение работать, но обычно это плохая идея;это побеждает всю цель использования строго типизированного языка.Typecasting говорит компилятору: «Я умнее вас, и я знаю, что это неправильно, но я хочу, чтобы вы игнорировали это и делали это в любом случае».

Лучшим решением было бы объявить вашу переменную так, как вы это сделали.y в вашем примере (Windows._FILETYPEA) или для объявления совместимого типа (type TMyFileTimeA = Windows._FILTETIMEA;).

См. Вики-страницы XE2 на Совместимость типов и идентичность .Посмотрите конкретно на раздел Assignment Compatibility.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...