Príklady generík Golang

Priklady Generik Golang



Generická funkcia Golang umožňuje vytvoriť opakovane použiteľný kód, ktorý je typovo bezpečný a kompatibilný so širokou škálou typov. Našťastie pridanie generík do Go otvára nové cesty pre opätovné použitie kódu a flexibilitu. Najnovšia verzia Golangu prináša veľmi očakávanú podporu pre generiká.

Ešte dôležitejšie je, že generiká zachovávajú silnú typovú bezpečnosť Go, ktorá umožňuje statickú kontrolu typu v čase kompilácie a zabezpečuje správnosť typu. Poskytujú štandardizované spracovanie chýb v rámci generického kódu, čo zlepšuje prehľadnosť a udržiavateľnosť. Okrem toho poskytujú štandardizované spracovanie chýb v rámci generického kódu, čo zlepšuje prehľadnosť a udržiavateľnosť. V tomto príspevku preskúmame niekoľko generických aplikácií a príkladov Go v reálnom svete.

Príklad 1: Použitie generickej funkcie Golang

Jedným z hlavných prípadov použitia generík je vytváranie funkcií, ktoré môžu fungovať na rôznych typoch. Tu uvádzame jeden z príkladov, kde sa používa všeobecná funkcia obvodu.







balík Hlavná
importovať 'fmt'
func obvod [ r int | plavák32 ]( polomer r ) {
c := 3 * 2 * polomer
fmt . Println ( 'Všeobecný obvod je:' , c )
}
func Hlavná () {
bol r1 int = 7
bol r2 plavák32 = 7 . 5
obvod ( r1 )
obvod ( r2 )
}

Na začiatku predchádzajúceho kódu riadok importuje balík „fmt“, ktorý poskytuje funkcie pre formátované I/O vrátane tlače výstupu na konzolu. Potom definujeme všeobecnú funkciu s názvom „obvod“, ktorá má polomer parametra všeobecného typu „r“, ktorý môže byť „int“ alebo „float32“. Vo vnútri funkcie vypočíta obvod vynásobením polomeru konštantnou hodnotou „3“ a následným vynásobením „2“. Nakoniec vytlačí vypočítaný obvod pomocou „fmt.Println“.



Ďalej máme hlavnú funkciu, kde sú dve premenné, r1 a r2, deklarované a priradené s hodnotami 7 a 7,5. Potom sa funkcia „obvod“ vyvolá dvakrát, pričom sa ako argumenty prenesú r1 a r2.



Výstup zobrazí výpočet vytlačením obvodov kruhov v nasledujúcom poradí:





Príklad 2:  Použitie všeobecného rozhrania Golang

Okrem toho nám generiká Golang pomáhajú s ich rozhraniami. Rozhrania v Go sú dôležitým nástrojom na uľahčenie opätovného použitia kódu a polymorfizmu. Generiká tým, že im umožňujú fungovať s mnohými typmi, zvyšujú výkon rozhraní. Nasleduje zdrojový kód generického rozhrania Golang:



balík Hlavná
importovať 'fmt'
typu EmpAge rozhranie {
int64 | int32 | plavák32 | plavák64
}
func newGenericFunc [ vek Vek ]( emp_Age age ) {
val := int ( emp_Age ) + 1
fmt . Println ( val )
}
func Hlavná () {
fmt . Println ( 'Vek zamestnancov' )
bol Vek1 int64 = 24
bol Vek2 plavák64 = 25 . 5
newGenericFunc ( Vek1 )
newGenericFunc ( Vek2 )
}

V predchádzajúcom zdrojovom kóde sme definovali rozhranie s názvom „EmpAge“, ktoré špecifikuje možné typy pre vek zamestnanca. Rozhranie zahŕňa typy int64, int32, float32 a float64. Toto rozhranie umožňuje „všeobecnej“ funkcii akceptovať ktorýkoľvek z týchto typov ako argument. Potom použijeme generickú funkciu s názvom newGenericFunc, ktorá preberá parameter emp_Age všeobecného typu veku, ktorým môže byť akýkoľvek typ, ktorý vyhovuje rozhraniu EmpAge. Vo vnútri funkcie skonvertuje emp_Age na int a zvýši ho o 1, ako je znázornené.

Ďalej deklarujeme dve premenné, Vek1 a Vek2, a priradíme im hodnoty 24 a 25,5 v hlavnej funkcii. Potom sa Age1 a Age2 odovzdajú ako parametre funkcii newGenericFunc, ktorá sa vykoná dvakrát. Týmto sa vek zvýši o 1 a vygenerujú sa aktualizované hodnoty.

Výstup, ktorý sa získa v nasledujúcom texte, sú veky zo všeobecnej funkcie, ktorá využíva rozhranie:

Príklad 3: Použitie generickej dátovej štruktúry Golang

Go generics nám navyše dáva možnosť vytvárať generické dátové štruktúry, ako sú zásobníky, fronty a prepojené zoznamy. Zvážte implementáciu generického zásobníka v nasledujúcom:

importovať 'fmt'
typu Stoh [ T akékoľvek ] [] T
func ( sv * Stoh [ T ]) TAM ( položka T ) {
sv = priložiť ( * sv , položka )
}
func ( sv * Stoh [ T ]) Pop () T {
ak len ( * sv ) == 0 {
panika ( 'Nič v zásobníku' )
}
index := len ( * sv ) - 1
položka := ( * sv )[ index ]
* sv = ( * sv )[: index ]
vrátiť položka
}
func Hlavná () {
stoh := Nový ( Stoh [ int ])
stoh . TAM ( 1 )
stoh . TAM ( 2 )
stoh . TAM ( 3 )
fmt . Println ( stoh . Pop ())
fmt . Println ( stoh . Pop ())
fmt . Println ( stoh . Pop ())
}

V predchádzajúcom kóde je definovaný generický typ s názvom „Zásobník“, ktorý predstavuje zásobník. Zástupný symbol „T“ umožňuje, aby zásobník obsahoval prvky akéhokoľvek typu. Typ „Stack“ je implementovaný ako segment prvkov typu „T“. Tu sú pre typ „Stack“ nasadené dve funkcie: „Push“ a „Pop“. Funkcia Push() je zodpovedná za pridávanie prvkov do zásobníka. Vezme položku argumentu typu „T“ a pripojí ju k základnému rezu pomocou funkcie append().

Zatiaľ čo funkcia Pop() vezme počiatočný komponent zo zásobníka a vráti ho, najprv určí, či je zásobník prázdny, a to vyhodnotením veľkosti pod ním ležiaceho rezu. Ak sa zásobník javí ako prázdny, čo spôsobí paniku, odošle sa hlásenie o chybe. V opačnom prípade získa posledný prvok z rezu, odstráni ho zo zásobníka rozrezaním rezu až po predposledný prvok a vráti odstránenú položku.

Potom sa vytvorí nový zásobník celých čísel pomocou syntaxe Stack[int] v rámci hlavnej funkcie tohto kódu. Potom sa trikrát zavolá metóda „Push“, aby sa do zásobníka pridali celé čísla 1, 2 a 3. Metóda „Pop“ sa však následne volá trikrát, aby sa získali a vytlačili prvky zo zásobníka.

Nasledujúci výstup indikuje, že prvky sú odstránené zo zásobníka v opačnom poradí:

Príklad 4: Použitie všeobecných obmedzení Golang

Go tiež ponúka vlastné obmedzenia, ktoré umožňujú veľkú flexibilitu a definujú špecifické požiadavky pre generické konštrukcie na základe ich aplikačných potrieb. Kód vlastných generických obmedzení je na demonštráciu uvedený nižšie:

balík Hlavná
importovať 'fmt'
typu Číslice rozhranie {
int64 | plavák64
}
func Hlavná () {
FloatValue := [] plavák64 { 2 . 0 , 4 . 0 , 6 . 0 , 8 . 0 , 10 . 0 }
IntegerValue := [] int64 { 2 , 4 , 6 , 8 , 10 }
súčet1 := genericSum ( FloatValue )
súčet2 := genericSum ( IntegerValue
fmt . Println ( 'Súčet float64:' , súčet1 )
fmt . Println ( 'Súčet int64:' , súčet2 )

}
func genericSum [ n Číslice ]( čísla [] n ) n {
bol ja som n
pre _ , na jeden := rozsah čísla {
súčet += na jeden
}
vrátiť súčet
}

V predchádzajúcom zdrojovom kóde definujeme rozhranie Numerics pomocou metódy „Sum“. Potom vytvoríme dva vlastné typy, „FloatValue“ a „IntegerValue“, ktoré implementujú rozhranie Numerics poskytnutím príslušných metód „Sum“. Funkcia genericSum je teraz schopná akceptovať rezy akéhokoľvek typu, ktorý vyhovuje rozhraniu Numerics. Vo vnútri funkcie iterujeme prvky a zavoláme metódu „Sum“ na výpočet súčtu. Nakoniec v hlavnej funkcii vytvoríme rezy FloatValue a IntegerValue a odovzdáme ich funkcii genericSum(), ktorá správne vypočíta súčet prvkov v každom reze.

Očakávaný výstup je teraz viditeľný na nasledujúcej obrazovke:

Záver

Preskúmali sme niekoľko praktických príkladov generík Go, ktoré zahŕňajú vytvorenie generickej dátovej štruktúry a generickej funkcie, definovanie generického rozhrania a použitie obmedzenia vlastného typu. Tieto príklady demonštrujú silu a flexibilitu, ktorú generiká prinášajú do programovacieho jazyka Go. Všimnite si, že generovanie generického kódu počas kompilácie zaisťuje efektívnu binárnu veľkosť a časy kompilácie.