Golang Generics Exempel

Golang Generics Exempel



Golangs generiska funktion gör det möjligt att skapa en återanvändbar kod som är typsäker och kompatibel med ett brett utbud av typer. Lyckligtvis öppnar tillägget av generika till Go nya vägar för kodåteranvändning och flexibilitet. Den senaste versionen av Golang för med sig det efterlängtade stödet för generika.

Ännu viktigare är att generics upprätthåller Gos starka typsäkerhet som möjliggör statisk typkontroll vid kompilering och säkerställer att typen är korrekt. De tillhandahåller en standardiserad felhantering inom generisk kod som förbättrar tydlighet och underhållbarhet. Dessutom tillhandahåller de en standardiserad felhantering inom den generiska koden som förbättrar tydlighet och underhållbarhet. I det här inlägget kommer vi att undersöka flera verkliga Go-generiska applikationer och exempel.

Exempel 1: Använda den allmänna Golang-funktionen

Ett av de primära användningsfallen för generika är att skapa funktioner som kan fungera på olika typer. Här går vi till ett av exemplen där den generiska omkretsfunktionen används.







paket huvud
importera 'fmt'
func omkrets [ r int | flyta 32 ]( radie r ) {
c := 3 * 2 * radie
fmt . Println ( 'Den generiska omkretsen är:' , c )
}
func huvud () {
var r1 int = 7
var r2 flyta 32 = 7 . 5
omkrets ( r1 )
omkrets ( r2 )
}

I början av föregående kod importerar raden 'fmt'-paketet som tillhandahåller funktioner för formaterad I/O, inklusive utskrift av utdata till konsolen. Sedan definierar vi en generisk funktion som heter 'omkrets' som tar en parameterradie av en generisk typ 'r' som kan vara antingen en 'int' eller en 'float32'. Inuti funktionen beräknar den omkretsen genom att multiplicera radien med det konstanta värdet på '3' och sedan multiplicera den med '2'. Slutligen skriver den ut den beräknade omkretsen med 'fmt.Println'.



Därefter har vi huvudfunktionen där två variabler, r1 och r2, deklareras och tilldelas värdena 7 respektive 7,5. Därefter anropas funktionen 'omkrets' två gånger och skickar r1 och r2 som argument.



Utdata visar beräkningen genom att skriva ut cirklarnas omkrets i följande:





Exempel 2:  Använda Golang Generic Interface

Dessutom hjälper Golang generika oss med deras gränssnitt. Gränssnitt i Go är ett viktigt verktyg för att underlätta kodåteranvändning och polymorfism. Genom att göra det möjligt för dem att fungera med många typer ökar generika kraften hos gränssnitt. Följande är källkoden för Golangs generiska gränssnitt:



paket huvud
importera 'fmt'
typ EmpAge gränssnitt {
int64 | int32 | flyta 32 | flyta64
}
func newGenericFunc [ ålder Ålder ]( emp_Age ålder ) {
val := int ( emp_Age ) + 1
fmt . Println ( val )
}
func huvud () {
fmt . Println ( 'Anställdas ålder' )
var Ålder 1 int64 = 24
var Ålder 2 flyta64 = 25 . 5
newGenericFunc ( Ålder 1 )
newGenericFunc ( Ålder 2 )
}

I den tidigare källkoden definierade vi ett gränssnitt med namnet 'EmpAge' som specificerar möjliga typer för en anställds ålder. Gränssnittet inkluderar typerna int64, int32, float32 och float64. Detta gränssnitt tillåter den 'generiska' funktionen att acceptera någon av dessa typer som ett argument. Efter det använder vi en generisk funktion som heter newGenericFunc som tar parametern emp_Age från en generisk typ av ålder som kan vara vilken typ som helst som uppfyller EmpAge-gränssnittet. Inuti funktionen konverterar den emp_Age till en int och ökar den med 1 som visas.

Därefter deklarerar vi de två variablerna, Age1 och Age2, och tilldelar värdena 24 respektive 25,5 i huvudfunktionen. Därefter skickas Age1 och Age2 som parametrar till funktionen newGenericFunc som genomgår en exekvering två gånger. Med detta höjs åldrarna med 1 och genererar de uppdaterade värdena.

Resultatet som ges i det följande är åldrarna från den generiska funktionen som använder gränssnittet:

Exempel 3: Användning av Golangs allmänna datastruktur

Dessutom ger Go generics oss också möjligheten att bygga generiska datastrukturer som stackar, köer och länkade listor. Överväg implementeringen av den generiska stacken i följande:

importera 'fmt'
typ Stack [ T någon ] [] T
func ( st * Stack [ T ]) Skjuta på ( artikel T ) {
st = bifoga ( * st , Artikel )
}
func ( st * Stack [ T ]) Pop () T {
om endast ( * st ) == 0 {
panik ( 'Inget i stack' )
}
index := endast ( * st ) - 1
Artikel := ( * st )[ index ]
* st = ( * st )[: index ]
lämna tillbaka Artikel
}
func huvud () {
stack := ny ( Stack [ int ])
stack . Skjuta på ( 1 )
stack . Skjuta på ( 2 )
stack . Skjuta på ( 3 )
fmt . Println ( stack . Pop ())
fmt . Println ( stack . Pop ())
fmt . Println ( stack . Pop ())
}

I den föregående koden definieras en generisk typ med titeln 'Stack' som representerar stacken. 'T'-platshållaren tillåter stapeln att hålla element av vilken typ som helst. Typen 'Stack' implementeras som en del av element av typen 'T'. Här distribueras två funktioner för typen 'Stack': 'Push' och 'Pop.' Funktionen Push() är ansvarig för att lägga till elementen i stacken. Den tar ett argumentobjekt av typen 'T' och lägger till det till den underliggande delen med hjälp av append()-funktionen.

Medan funktionen Pop() tar den initiala komponenten från stacken och returnerar den, avgör den först om stacken är tom genom att utvärdera storleken på den underliggande delen. Ett felmeddelande skickas om stacken verkar vara tom vilket orsakar panik. Annars hämtar den det sista elementet från skivan, tar bort det från stapeln genom att skiva upp skivan till det näst sista elementet och returnerar det borttagna objektet.

Därefter skapas den nya stapeln med heltal med hjälp av Stack[int]-syntaxen inom huvudfunktionen för denna kod. Därefter anropas sedan 'Push'-metoden tre gånger för att lägga till heltal 1, 2 och 3 till stacken. Men 'Pop'-metoden anropas tre gånger efteråt för att hämta och skriva ut elementen från stacken.

Följande utdata indikerar att elementen tas bort från stapeln i omvänd ordning:

Exempel 4: Använda Golang Generic Constraints

Go erbjuder också anpassade begränsningar som möjliggör stor flexibilitet och definierar specifika krav för generiska konstruktioner baserat på deras applikationsbehov. Koden för de anpassade generiska begränsningarna tillhandahålls i följande för demonstration:

paket huvud
importera 'fmt'
typ Numerics gränssnitt {
int64 | flyta64
}
func huvud () {
FloatValue := [] flyta64 { 2 . 0 , 4 . 0 , 6 . 0 , 8 . 0 , 10 . 0 }
Heltalsvärde := [] int64 { 2 , 4 , 6 , 8 , 10 }
summa1 := generisk Summa ( FloatValue )
summa2 := generisk Summa ( Heltalsvärde
fmt . Println ( 'Summa av float64 :' , summa1 )
fmt . Println ( 'Summa av int64 :' , summa2 )

}
func generisk Summa [ n Numerik ]( tal [] n ) n {
var Jag är n
för _ , på ett := räckvidd tal {
belopp += på ett
}
lämna tillbaka belopp
}

I den tidigare källkoden definierar vi Numerics-gränssnittet med 'Sum'-metoden. Sedan skapar vi två anpassade typer, 'FloatValue' och 'IntegerValue', som implementerar Numerics-gränssnittet genom att tillhandahålla sina respektive 'Sum'-metoder. Funktionen genericSum kan nu acceptera skivor av vilken typ som helst som uppfyller Numerics-gränssnittet. Inuti funktionen itererar vi över elementen och anropar 'Sum'-metoden för att beräkna summan. Slutligen, i huvudfunktionen skapar vi segmenten av FloatValue och IntegerValue och skickar dem till funktionen genericSum() som korrekt beräknar summan av elementen i varje segment.

Den förväntade utgången är nu synlig på följande skärm:

Slutsats

Vi utforskade några praktiska exempel på Go generics som inkluderar skapandet av en generisk datastruktur och generisk funktion, definiera ett generiskt gränssnitt och använda den anpassade typbegränsningen. Dessa exempel visar kraften och flexibiliteten som generika tillför programmeringsspråket Go. Observera att generering av generisk kod under kompileringen säkerställer effektiv binär storlek och kompileringstider.