Dans Pascal il y a deux types de déclarations de type:
Le premier est que créer un raccourci pratique, comme typedef em> C. Les alias sont compatibles l'un à l'autre et de leur type d'origine. Les types créés sont volontairement incompatibles et ne peuvent pas être mélangés sans explicite et dangereux par typecast définition. P> Maintenant, nous allons prendre fonction renvoyant l'ancien alias de type et nourrir son résultat à la fonction attendant ce dernier celui-ci: p> type T1 = array of string; T2 = array of string;
procedure TForm1.FormCreate(Sender: TObject);
function Generator: T1;
begin Result := T1.Create('xxx', 'yyy', 'zzz'); end;
procedure Consumer (const data: T2);
begin
with TStringList.Create do
try
AddStrings(data);
Self.Caption := CommaText;
finally
Free;
end;
end;
begin
Consumer(Generator);
end;
uses Classes, IOUtils;
TStringList.Create.AddStrings(
TDirectory.GetFiles('c:\', '*.dll') );
TStringList.Create.AddStrings(
TArray<string>( // this is required by compiler - but why ???
TDirectory.GetFiles('c:\', '*.dll') ) );
3 Réponses :
Delphi est une langue fortement typée. Cela signifie que identiques (dans ce cas, je veux dire que leurs définitions ont l'air exactement les mêmes) ne sont pas compatibles.
Lorsque vous écrivez ne sont pas compatibles compatibles. P> même chose pour P> Tableau de type
TStringDynArray = array of string;
TArray<T> = array of string;
OOOKAY, Donc, vous faites Tstringdynarray = TARRAY windows.dord = system.types.dword; code> et system.types.dordle = system.longword; code> et attendez-vous à ce qu'ils soient compatibles? Et quel est le sens de type x = type y code> de construction gauche? Par "Autres problèmes" U signifie une compatibilité ascendante avec des bibliothèques faites pour les versions antérieures de Delphi? Comme Things Extension n'a pas expliqué que IOUTILS ou vice versa? L'aliénation de type inutile l'a fait!
@ Arioch'the: Désolé, c'était une faute de frappe. Je voulais dire TStringdynarray = TARRAY
@Arioch: type x = type y code> crée une nouvelle RTTI pour X. Vous pouvez donc savoir si vous avez un TMYSTRING ou TYOURSTRING avec "=" chaîne de type ". Les types simples sont compatibles avec une affectation. Mais un tableau est un type complexe ("construit") comme un enregistrement.
Tstringdynarray = Tarray
@DavidHeffernan Oui, il y aurait parce qu'il n'y aurait qu'un seul TARRAY t1 = TARRAY T2 = TARRAY
Oui, je vois que c'est vrai maintenant. dit "Deux génériques instanciés sont considérées comme étant compatibles si les types de base sont identiques ( ou sont des alias à un type commun) et les arguments de type sont identiques. "
Cela pourrait avoir du sens dans Turbopascal, où (1) Tous les tableaux avaient une longueur fixe, (2) U ne pouvait que renvoyer des types simples des fonctions. Pour ce que je me souviens, des types construits ne pouvaient pas être attribués du tout, le compilateur n'a pas su comment le faire. Vous deviez donc utiliser des paramètres var-paramètres et des alias de type unioque. Mais maintenant, il n'y a pas de sens technique dans cela, le compilateur n'est pas si limité maintenant. Et cette restriction inutile dommageait sérieusement la flexibilité de la composition du programme. C'est l'héritage de l'ancien compilateur et il n'y a pas de bien dans cet héritage!
T1 = TARRAY T1 = Taille de chaîne et T2 = tableau de chaîne code> ne le sont pas. Et tableau de string = TARRAY
@Ariamch Si vous définissez deux types différents, même si elles ont l'air de même, il y a une raison pour laquelle vous le faites. Et c'est pourquoi ils ne sont pas compatibles les uns aux autres. Si vous voulez qu'ils soient compatibles, utilisez un type au lieu de 2. Il y a une raison derrière elle. Si tel était comme si vous souhaitez que vous souhaitiez: Aujourd'hui, les deux types sont identiques et le programme compile simplement bien et fonctionne. Demain, l'un des 2 types est changé et que rien ne compile plus.
Regardons le problème d'un angle de plus. Quelle est la raison d'être pour Tarray de Tarray
Si vous définissez deux types différents, même si elles ont la même raison, il y a une raison pour laquelle vous le faites. I> - c'est exactement cela mentionné type TFilename = type chaîne de type code> construction. Lorsque j'utilise un type simple type code> - Je ne définit différents types i>. Delphi fait, ne me laissant aucun choix. Si vous voulez qu'ils soient compatibles, utilisez un type au lieu de 2 i> même Embarcadero lui-même n'a pas pu le faire. Comment imaginez-vous toute la communauté de différentes années de territoire le ferait? Allez! Nous n'avons toujours pas un vrai incluant avec les versions de l'IFDEF pour le compilateur. Chaque bibliothèque a et maniaque c'est propre. Une telle chose simple!
Maintenant, vous jugez pratique de faire un système de type unifié uniforme un peu? Sans migrer vers CLR / JVM? Avec un soutien aux bibliothèques et compilateurs quelques années d'avant en arrière?
Demain L'un des 2 types se change et la flèche Rien ne compile plus i> Oui, oui, exactement! Mais c'est pire! Vous me forcez à utiliser des typastes explicites où il n'y a pas besoin pour eux. Donc demain, quand un type change - cela compilerait - mais ne fonctionnerait pas. Delphi applique le développeur pour désactiver la typification! Ou vous pouvez appeler cette "remplacement" doucement. Et quand demain les types couraient vraiment incompatibles - le développeur obtiendrait une sorte de Pansichar (Unicodestring), qui compilerait bien, mais ne fonctionnerait pas.
Ouais, je sens la même chose. Je définis un alias à un autre type et vous prétendiez que j'avais l'intention d'isoler ces types. Je n'étais pas, ne dis pas ce qui ne l'est pas! Mais vous venez de me laisser sans choisir.
La clé pour comprendre ce problème est le type compatibilité et identité sujet dans le Guide de la langue. Je suggère que vous ayez une bonne lecture de ce sujet.
Il est également utile de simplifier l'exemple. L'inclusion des génériques dans l'exemple sert principalement à compliquer et à confondre les choses. P> de la documentation: p> Lorsqu'un identifiant de type est déclaré à l'aide d'un autre identifiant de type, sans qualification, ils désignent le même type. P>
blockQquote> Ceci signifie que Un peu plus loin dans la documentation est-ce: p> Constructions linguistiques qui fonctionnent comme noms de type indiquent un type différent à chaque fois qu'ils se produisent. P>
blockQuote> Les déclarations de Nous devons maintenant examiner la section discutant de la compatibilité. Cela donne un ensemble de règles à suivre pour déterminer si deux types sont compatibles ou non compatibles. Nous pouvons en fait raccourci que la discussion en se référant à une autre rubrique d'aide: types structurés, types de réseau et missions qui états clairement: P> Les matrices sont compatibles-compatibles uniquement si elles sont du même type. P>
blockQquote> Ceci indique clairement pourquoi l'affectation Votre code a regardé les paramètres de passage, mais la mine axée sur la mission . Les problèmes sont les mêmes car, comme le Procédures et fonctions d'appel Sujet d'aide explique: P> < BlockQuote>
Lorsque vous appelez une routine, rappelez-vous que: p>
Tinteger1 code> et Tinteger2 code> sont le type même fort> le même type que integer code>. p>
TARRAY1 code> et TARRAY2 code> tomber dans cette catégorie. Et cela signifie que ces deux identifiants désignent différents types. P>
array1: = array2 code> donne une erreur de compilateur. P>
Chaque type est compatible avec lui-même. Deux types distincts sont compatibles s'ils répondent au moins une des conditions suivantes. I> -et LOOOONG Liste des cas spéciaux. Qu'est-ce qui signifie essentiellement? Que les restrictions de l'école de vanille Pascal ou du Turbo Compilateur Turbo au début entrent désormais la composition des programmes réels. Oui, ces types sont formellement différents, mais ils sont pratiquement compatibles. L'exemple affirme créer deux types distincts, TS1 et TS2. I> mais il prétend qu'ils sont compatibles i>. Qu'est-ce que c'est ? Il est pratique de nier de constructions formelles. Les tableaux doivent également être compatibles!
Et non, je me soucie peu de fumeur var1: = var2 code>. Il a peu de sens pratique (pour la plupart des moments). Vous pourriez avoir besoin var1: = expression-with-var2 code>, mais quelles sont les expressions avec des enregistrements et des tableaux? Ils sont une sorte de fonctions. Mapréduce et tel. Donc, je me soucie de la facilité des fonctions de chaînage, de la source expressif laconique. L'affectation entre Vars ne m'aiderait pas beaucoup, mais lorsque je dois ajouter beaucoup de chaudières, il suffit de combiner deux fonctions standard - c'est des tours cachées sur la piste de course à pied!
"Et non, je me soucie peu de FIRECT VAR1: = VAR2". Pourquoi pas? Le passage des paramètres à une procédure est à peu près la même chose que l'attribution à une variable. Et ainsi, l'affectation-compatibilité est la nuit de la question ici. C'est précisément quelle est votre question. Réécrire mon exemple de code en termes de paramètre passant si vous préférez, les conclusions sont exactement les mêmes. Cela ne répond pas à votre question? Je sais que c'est frustrant pour vous, mais les règles sont les règles et nous ne pouvons pas les changer. Seul EMBA peut les changer.
Passer des paramètres à une procédure est à peu près i> Oui, dans le même sens que la programmation à Delphi est le nom de la programmation en tant que programmation dans l'assembleur. Toutes les langues de Turing-complètent sont simplement Syntaxe Sugar l'un pour l'autre. Mais dans vraiment je n'utilise pas beaucoup d'affectation directe non-mutating. Cela a juste peu de sens pratique. Mais j'appelle un seul résultat des fonctions d'un autre. Si le compilateur le traite comme Attributant - que ce soit, c'est son choix interne. Je me soucie de la compatibilité = composition des expressions et des fonctions.
Seul EMBA peut les changer. I> Et nous pouvons élever la question. Nous pouvons demander 'Bonjour! Delphi est à bout d'enfin! Tapez pour passer à autre chose! ' Et le fait que l'EMBA a commis une erreur dans son RTL juste un bon moment pour élever la voix. Comme des commentaires anti-msie sur les sites Microsoft, cette affaire se produit que cette restriction héritée a perdu du sens pratique et que fermer uniquement la productivité. EMBA RTL Architects - Le plus éclairé et expérimenté - Impossible de rendre compte de cette restriction. Si cela ne montre pas à quel point cette restriction est issue de NovaDays, je ne sais pas ce qui peut être.
Les liens de documentation que j'ai fournis expliquent les règles que le compilateur suit. Pourquoi ces règles sont donc si bienvenues à la naissance de Pascal.
Oui, hier j'ai jeté un coup d'œil à "Signaler Pascal" de 1949/1974, et cette règle y attend bien. Pas une telle chose comme "Open Array", vous ne pouvez pas faire Procédure XXX (Liste YY: Array of Byte) Code>; Tout doit avoir le nom. Et vous seuls les petits petits extraits comme le tri des bulles pour votre travail scolaire, aucun code d'autre, votre propre code d'hier de l'année, alors oui, vous pourriez planifier Al les types de données. En 1949, vous pourriez. Mais aujourd'hui, c'est juste une incohérence.
Il n'y a aucun point à me plaindre. C'est Emba que vous devez parler. Changer TStringDynarray = TARRAY
J'ai fait, j'ai ouvert le billet QC et j'essaie d'attirer l'attention de la communauté aussi. Pourtant, personne n'a signalé de bon effet de cette restriction. Puissions-nous tous demander à EMBA de changer cela? change systématiquement comme ils l'ont fait avec une matrice ouverte, ne pas le patcher un type après l'autre. Je leur ai demandé, n'hésitez pas à rejoindre QC et à exprimer votre opinion!
J'ai aussi eu le même problème avec Delphi, où je voulais transmettre des valeurs d'un tableau identique à un autre. Non seulement j'ai des problèmes « d'incompatibilité » avec deux comme des affectations de tableau, mais je ne pouvais pas utiliser aussi le « Copier () » procédure b>. Pour contourner ce problème, je trouve que je pouvais utiliser un pointeur sur un type b> tableau de tableau de chaînes, au lieu.
Par exemple: p>
New_Two_Dimensional_Fixed_Array[10][1]
Pas besoin d'apporter des génériques à cela. Essayez
type t1 = tableau de chaîne; T2 = tableau de chaîne code> puis tente d'attribuer une variable de type T1 à l'une de type T2.