Примери за генерични продукти на Golang

Primeri Za Genericni Produkti Na Golang



Генеричната функция на Golang прави възможно създаването на код за многократна употреба, който е безопасен за тип и съвместим с широка гама от типове. За щастие, добавянето на генерични продукти към Go отваря нови пътища за повторно използване на кода и гъвкавост. Последната версия на Golang носи със себе си дългоочакваната поддръжка за генерични продукти.

По-важното е, че генериците поддържат силната безопасност на типа на Go, която позволява проверка на статичен тип по време на компилиране и гарантира коректността на типа. Те осигуряват стандартизирано обработване на грешки в рамките на общ код, което подобрява яснотата и поддръжката. Освен това те осигуряват стандартизирано обработване на грешки в общия код, което подобрява яснотата и поддръжката. В тази публикация ще разгледаме няколко реални Go генерични приложения и примери.

Пример 1: Използване на генеричната функция Golang

Един от основните случаи на използване на генерични продукти е създаването на функции, които могат да работят с различни типове. Тук отиваме с един от примерите, където се използва общата функция за обиколка.







пакет основен
импортиране 'fmt'
функ обиколка [ r вътр | float32 ]( радиус r ) {
° С := 3 * 2 * радиус
fmt . Println ( 'Общата обиколка е: ' , ° С )
}
функ основен () {
беше r1 вътр = 7
беше r2 float32 = 7 . 5
обиколка ( r1 )
обиколка ( r2 )
}

В началото на предишния код редът импортира пакета „fmt“, който предоставя функции за форматиран I/O, включително отпечатване на изхода към конзолата. След това дефинираме обща функция, наречена „обиколка“, която приема параметър радиус от общ тип „r“, който може да бъде „int“ или „float32“. Във функцията тя изчислява обиколката, като умножава радиуса по постоянната стойност на „3“ и след това го умножава по „2“. Накрая той отпечатва изчислената обиколка с помощта на “fmt.Println”.



След това имаме главната функция, където две променливи, r1 и r2, се декларират и им се присвояват съответно стойностите 7 и 7,5. След това функцията “circumference” се извиква два пъти, предавайки r1 и r2 като аргументи.



Резултатът показва изчислението чрез отпечатване на обиколките на кръговете по следния начин:





Пример 2:  Използване на генеричния интерфейс на Golang

Освен това генеричните продукти на Golang ни помагат с техните интерфейси. Интерфейсите в Go са жизненоважен инструмент за улесняване на повторното използване на кода и полиморфизма. Като им позволяват да функционират с много типове, генеричните продукти увеличават мощността на интерфейсите. Следва изходният код на генеричния интерфейс на Golang:



пакет основен
импортиране 'fmt'
Тип EmpAge интерфейс {
int64 | int32 | float32 | float64
}
функ newGenericFunc [ възраст Възраст ]( emp_Age възраст ) {
вал := вътр ( emp_Възраст ) + 1
fmt . Println ( вал )
}
функ основен () {
fmt . Println ( „Възраст на служителите“ )
беше Възраст1 int64 = 24
беше Възраст2 float64 = 25 . 5
newGenericFunc ( Възраст1 )
newGenericFunc ( Възраст2 )
}

В предишния изходен код дефинирахме интерфейс, наречен „EmpAge“, който указва възможните типове за възрастта на служителя. Интерфейсът включва типовете int64, int32, float32 и float64. Този интерфейс позволява на „генеричната“ функция да приема всеки от тези типове като аргумент. След това използваме обща функция, наречена newGenericFunc, която приема параметъра emp_Age на общ тип възраст, който може да бъде всеки тип, който удовлетворява интерфейса на EmpAge. Вътре във функцията тя преобразува emp_Age в int и го увеличава с 1, както е показано.

След това декларираме двете променливи, Age1 и Age2, и присвояваме стойностите съответно 24 и 25,5 в основната функция. След това Age1 и Age2 се предават като параметри към функцията newGenericFunc, която се подлага на изпълнение два пъти. С това възрастите се повишават с 1 и генерират актуализираните стойности.

Резултатът, който се получава в следното, са възрастите от генеричната функция, която използва интерфейса:

Пример 3: Използване на генеричната структура на данни на Golang

Освен това Go generics също ни дава възможност да изграждаме общи структури от данни като стекове, опашки и свързани списъци. Помислете за изпълнението на общия стек в следното:

импортиране 'fmt'
Тип Стек [ Т всякакви ] [] T
функ ( ул * Стек [ T ]) Бутане ( т. Т ) {
ул = добавям ( * ул , вещ )
}
функ ( ул * Стек [ T ]) Поп () T {
ако само ( * ул ) == 0 {
паника ( „Нищо в стека“ )
}
индекс := само ( * ул ) - 1
вещ := ( * ул )[ индекс ]
* ул = ( * ул )[: индекс ]
връщане вещ
}
функ основен () {
стек := нов ( Стек [ вътр ])
стек . Бутане ( 1 )
стек . Бутане ( 2 )
стек . Бутане ( 3 )
fmt . Println ( стек . Поп ())
fmt . Println ( стек . Поп ())
fmt . Println ( стек . Поп ())
}

В предишния код е дефиниран общ тип, озаглавен „Стек“, който представлява стека. Контейнерът „T“ позволява на стека да съдържа елементи от всякакъв тип. Типът „Стек“ е реализиран като срез от елементи от тип „T“. Тук са разгърнати две функции за типа „Stack“: „Push“ и „Pop“. Функцията Push() отговаря за добавянето на елементите към стека. Той взема аргументен елемент от тип „T“ и го добавя към основния срез с помощта на функцията append().

Докато функцията Pop() взема първоначалния компонент от стека и го връща, тя първо определя дали стекът е празен, като оценява размера на основния срез. Изпраща се известие за грешка, ако стекът изглежда празен, което предизвиква паника. В противен случай той извлича последния елемент от среза, премахва го от стека, като нарязва среза до предпоследния елемент и връща премахнатия елемент.

След това новият стек от цели числа се създава с помощта на синтаксиса Stack[int] в рамките на основната функция на този код. След това методът „Push“ се извиква три пъти, за да добави целите числа 1, 2 и 3 към стека. Въпреки това, методът „Pop“ се извиква три пъти впоследствие, за да извлече и отпечата елементите от стека.

Следният изход показва, че елементите са премахнати от стека в обратен ред:

Пример 4: Използване на общите ограничения на Golang

Go също така предлага персонализирани ограничения, които позволяват голяма гъвкавост и определят специфични изисквания за общи конструкции въз основа на нуждите на техните приложения. Кодът на персонализираните общи ограничения е предоставен в следното за демонстрация:

пакет основен
импортиране 'fmt'
Тип Числа интерфейс {
int64 | float64
}
функ основен () {
FloatValue := [] float64 { 2 . 0 , 4 . 0 , 6 . 0 , 8 . 0 , 10 . 0 }
IntegerValue := [] int64 { 2 , 4 , 6 , 8 , 10 }
сума1 := genericSum ( FloatValue )
сума2 := genericSum ( IntegerValue
fmt . Println ( 'Сума от float64:' , сума1 )
fmt . Println ( 'Сума от int64:' , сума2 )

}
функ genericSum [ n Числа ]( числа [] н ) н {
беше аз съм n
за _ , никой := диапазон числа {
сума += никой
}
връщане сума
}

В предишния изходен код ние дефинираме интерфейса Numerics с метода „Sum“. След това създаваме два персонализирани типа, „FloatValue“ и „IntegerValue“, които имплементират интерфейса Numerics, като предоставят съответните си методи „Sum“. Функцията genericSum вече може да приема срезове от всякакъв тип, които отговарят на интерфейса Numerics. Вътре във функцията обикаляме елементите и извикваме метода „Sum“, за да изчислим сумата. И накрая, в главната функция създаваме срезовете на FloatValue и IntegerValue и ги предаваме на функцията genericSum(), която правилно изчислява сумата на елементите във всеки срез.

Очакваният изход вече се вижда на следния екран:

Заключение

Разгледахме някои практически примери за генерични продукти на Go, които включват създаването на обща структура от данни и обща функция, дефиниране на общ интерфейс и използване на персонализирано ограничение за тип. Тези примери демонстрират силата и гъвкавостта, които генериците внасят в езика за програмиране Go. Обърнете внимание, че генерирането на генеричен код по време на компилация гарантира ефективния двоичен размер и времето за компилиране.