Am văzut de multe ori afirmații de genul „Vă rugăm să faceți această funcție un cetățean de primă clasă într-un astfel de limbaj / platformă”. De exemplu, se spune despre enumerările în C # /. Net. Deci, când este considerată o caracteristică un „cetățean de primă clasă” într-un limbaj / platformă de programare?

Comentarii

Răspuns

Definiție

Un obiect este de primă clasă atunci când:

  • poate fi stocat în variabile și structuri de date
  • poate fi transmis ca parametru unui subrutină
  • poate fi returnat ca rezultat al unui subrutină
  • poate fi construit în timp de execuție
  • are identitate intrinsecă (independent de orice nume dat)

Termenul „obiect” este folosit vag aici, nu se referă neapărat la obiecte din programarea orientată pe obiecte. Cele mai simple tipuri de date scalare, cum ar fi numerele întregi și cu virgulă mobilă, sunt aproape întotdeauna de primă clasă.

http://en.wikipedia.org/wiki/First_class_object

Comentarii

  • Deci, ceea ce face ca enumerările să devină obiect de clasa a doua în .net / C #?
  • @Gulshan – ați putea argumenta lipsa identității intrinseci – Enumeriile C # sunt practic doar zahăr sintactic (adică un nume ” div id = „d6c985c9ee”>

) pentru o valoare întreagă. Comparați cu Java, unde enumerările sunt obiecte în sine.

  • @mikera, în .NET enumurile sunt valori în sine. Java pur și simplu nu are valori, doar obiecte, care ‘ este singura diferență.
  • @mikera: Deși asta împiedică Java ‘ presupune că au proprietăți frumoase, cum ar fi posibilitatea de a reprezenta câmpuri de biți cu ele. Deși implementarea lor este probabil mai de primă clasă, majoritatea API-urilor lor au încă o mulțime de constante întregi (sau șiruri) și multe utilizări ale acestora nu pot fi ușor înlocuite cu enumerări.
  • Nu ‘ nu cred că enumurile pot fi construite în timp de execuție în .Net, nu-i așa? Am crezut că sunt mereu constante.
  • Răspuns

    Noțiunea de ” cetățean de primă clasă ” sau ” element de primă clasă ” într-un limbaj de programare a fost introdus de informaticianul britanic Christopher Strachey în anii 1960 în contextul primului -funcții de clasă. Cea mai faimoasă formulare a acestui principiu este probabil în Structura și interpretarea programelor de calculator de Gerald Jay Sussman și Harry Abelson:

    • Acestea pot fi numite după variabile.
    • Pot fi transmise ca argumente la proceduri.
    • Pot fi returnate ca rezultate ale proceduri.
    • Acestea pot fi incluse în structurile de date.

    Practic, înseamnă că puteți face acest lucru element de limbaj de programare tot ceea ce puteți face cu toate celelalte elemente din limbajul de programare.

    Este vorba despre ” drepturi egale „: puteți face toate cele de mai sus, cu, să zicem, numere întregi, așa că de ce ar trebui să fie alt lucru diferit?

    Definiția de mai sus este puțin restrictivă în sensul că este doar într-adevăr vorbește despre aspectul de primă clasă ca fiind legat de obiectele programului. O definiție mai generală wou Aș fi că un lucru este de primă clasă, dacă poți face totul cu el, poți face și cu alte lucruri de tip similar.

    De exemplu, operatorii Java și metodele Java sunt de tip similar. Puteți defini metode noi, puteți alege (oarecum) liber numele propriilor metode, puteți suprascrie metodele, puteți suprasolicita metodele. James Gosling poate face toate acestea și cu operatorii, dar tu și cu mine nu putem. Adică, contrar credinței populare, Java nu acceptă supraîncărcarea operatorului: de exemplu , operatorul + este suprasolicitat pentru byte, short, int, long, float, double și String și IIRC în Java 7, de asemenea, pentru BigInteger și BigDecimal (și probabil un cuplu pe care l-am uitat), doar că tu nu ai nicio influență asupra acestuia.Acest lucru face în mod clar operatorii de clasa a doua în conformitate cu această a doua definiție. Rețineți că metodele încă nu sunt obiecte de primă clasă, în conformitate cu prima definiție. (Aceasta face ca operatorii să fie de clasa a treia?)

    Comentarii

    • Răspuns excelent. Deci, de exemplu, documente pipenv spun ” Windows este un cetățean de primă clasă, în lumea noastră. ” Ar implica acest lucru că puteți face tot cu pipenv pe Windows pe care îl puteți face și pe Linux?
    • Nu, nu ‘ nu cred că utilizarea termenului ” cetățean de primă clasă ” are ceva de-a face cu definiția formală a programării limbajului de programare a termenului. Cred că pipenv folosesc doar termenul cu sensul său normal în engleză standard.
    • Ca și în ” tratat corect? ” Vă mulțumim pentru ajutor.

    Răspuns

    De obicei, acest refe rs la o construcție care este acceptabilă ca parametru, poate fi definită ca un tip de returnare dintr-o funcție sau i se poate atribui o valoare. În mod normal, trebuie să le puteți construi în timpul rulării. De exemplu, o instanță a unei clase ar fi un cetățean de primă clasă în c ++ sau java, dar o funcție în C nu ar fi.

    Comentarii

    • Ce face ca o clasă să fie un cetățean de primă clasă în c ++?
    • @bjarkef: Suna că a fost deja răspuns potrivindu-se cu descrierea oferită în propozițiile precedente.
    • @Jonathan: Da, îmi pare rău, am citit greșit ” construindu-le la runtime „. Da, puteți construi o instanță a unei clase în timp de execuție (un obiect), dar nu clasa în sine. Asta m-a încurcat.
    • Trecerea după parametru nu este încă suficientă. În C / C ++ aș considera în continuare funcțiile ca cetățeni de clasa a doua. Ele pot fi transmise ca parametri, returnate ca rezultate plasate în alte obiecte. Dar ele nu pot fi manipulate fără ajutorul altor constructe (cum ar fi std :: bind este necesar pentru a lega parametrii de o funcție).
    • @Martin Nu am spus niciodată că funcțiile erau cetățeni de primă clasă în C / C ++ .

    Răspuns

    Aș spune că o caracteristică este un cetățean de primă clasă dacă este implementată numai de limbă .
    adică nu necesită funcții cu mai multe limbi sau o bibliotecă standard pentru a implementa acea caracteristică.

    Exemplu:

    În C / C ++ nu consider funcțiile ca fiind o primă cetățean de clasă (alții pot).
    Acest lucru se datorează faptului că există modalități de a manipula funcții care sunt susținute direct de limbă, dar necesită utilizarea altor caracteristici lingvistice. Legarea parametrilor la o funcție nu este acceptată direct și trebuie să construiți un functor pentru a implementa această caracteristică.

    Comentarii

    • Nu ar ‘ t care fac ca funcțiile legate (sau ” închiderile „) să nu fie de primă clasă, în timp ce funcțiile în sine sunt? Cum participă 0x ‘ pentru analiza dvs.?
    • @Fred Nurk: Totul depinde de limbă. În unele limbi, închiderile sunt sisteme de primă clasă. În altele nu. Încă nu sunt suficient de familiarizat cu C ++ 0x pentru a face un comentariu explicit.
    • Să ‘ să spunem că limba este fie C, fie C ++ (dar nu 0x ), ca și în care răspundeți. ‘ nu ar face definiția dvs. ” de primă clasă ” nu ar face funcții legate (sau ” închiderile „) nu trebuie să fie de primă clasă, în timp ce funcțiile în sine sunt?
    • @Fred Nurk: Dacă limitați singurul lucru pe care îl puteți face cu o funcție este să le faceți o închidere, atunci sigur. Dar pentru mine, ‘ îmi place să spun dacă platforma acceptă adăugarea de numere întregi numai prin importul unei biblioteci. Atunci numerele întregi sunt cetățeni de primă clasă, dar adăugarea numerelor întregi nu este luată în considerare. În opinia mea, închiderea este o operație care poate fi efectuată pe o funcție care returnează efectiv o nouă funcție (dar depinde de modul în care o definiți). Însă închiderea și legarea sunt doar două operații, câte altele excludem din discuție (nu sunt sigur că a fost o întrebare).
    • @ Martin: Nu trebuie să mă explic clar. Având în vedere ” o caracteristică este un cetățean de primă clasă dacă este implementată numai de limba „, atunci sunt implementate funcții atât în C, cât și în C ++. numai prin limbă și ar fi astfel de primă clasă. Funcțiile legate (care pot fi numite și ” închideri „) sunt ceea ce ‘ re vorbind despre parametrii de legare etc., dar că ‘ este o caracteristică diferită.

    Răspuns

    Pentru a adăuga un exemplu la răspunsurile deja furnizate:

    În WCF / C # trebuie să marcați în prezent un obiect de clasă cu un atribut de contract de servicii pentru ca acesta să funcționeze ca serviciu. Nu există așa ceva:

    public **service** MyService (in relation public **class** MyClass). 

    O clasă este un cetățean de primă clasă în c #, unde un serviciu nu este.

    Speranță acest lucru ajută

    Lasă un răspuns

    Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *