דוגמאות גנריות של גולנג

Dwgm Wt Gnrywt Sl Gwlng



התכונה הגנרית של Golang מאפשרת ליצור קוד לשימוש חוזר, בטוח מסוגים ותואם למגוון רחב של סוגים. למרבה המזל, התוספת של גנריות ל-Go פותחת אפיקים חדשים לשימוש חוזר בקוד וגמישות. הגרסה העדכנית ביותר של Golang מביאה איתה את התמיכה הצפויה בגנריות.

חשוב מכך, גנריקה שומרת על בטיחות הסוג החזקה של Go המאפשרת בדיקת סוגים סטטיים בזמן ההידור ומבטיחה את תקינות הסוג. הם מספקים טיפול סטנדרטי בשגיאות בתוך קוד גנרי אשר משפר את הבהירות והתחזוקה. בנוסף, הם מספקים טיפול סטנדרטי בשגיאות בתוך הקוד הגנרי, אשר משפר את הבהירות והתחזוקה. בפוסט זה, נבחן את מספר היישומים והדוגמאות הגנריות של Go בעולם האמיתי.

דוגמה 1: שימוש בפונקציה הגנרית של Golang

אחד ממקרי השימוש העיקריים בגנריות הוא יצירת פונקציות שיכולות לפעול על סוגים שונים. כאן, אנו הולכים עם אחת הדוגמאות שבהן נעשה שימוש בפונקציית ההיקף הגנרית.







חֲבִילָה רָאשִׁי
יְבוּא 'fmt'
func הֶקֵף [ ר int | לצוף32 ]( רדיוס r ) {
ג := 3 * 2 * רַדִיוּס
fmt . Println ( 'ההיקף הגנרי הוא:' , ג )
}
func רָאשִׁי () {
היה r1 int = 7
היה r2 לצוף32 = 7 . 5
הֶקֵף ( r1 )
הֶקֵף ( r2 )
}

בתחילת הקוד הקודם, השורה מייבאת את חבילת 'fmt' המספקת פונקציות ל-I/O מעוצב, כולל הדפסת הפלט לקונסולה. לאחר מכן, אנו מגדירים פונקציה גנרית בשם 'היקף' שלוקחת רדיוס פרמטר מסוג 'r' גנרי שיכול להיות 'int' או 'float32'. בתוך הפונקציה, הוא מחשב את ההיקף על ידי הכפלת הרדיוס בערך הקבוע של '3' ולאחר מכן הכפלתו ב-'2'. לבסוף, הוא מדפיס את ההיקף המחושב באמצעות 'fmt.Println'.



לאחר מכן, יש לנו את הפונקציה הראשית שבה שני משתנים, r1 ו-r2, מוכרזים ומוקצים עם הערכים 7 ו-7.5, בהתאמה. לאחר מכן, הפונקציה 'היקף' מופעלת פעמיים, תוך העברת r1 ו-r2 כארגומנטים.



הפלט מציג את החישוב על ידי הדפסת היקפי העיגולים בקטע הבא:





דוגמה 2:  שימוש בממשק הגנרי של Golang

יתרה מכך, הגנריות של Golang מסייעות לנו בממשקים שלהן. ממשקים ב-Go הם כלי חיוני כדי להקל על שימוש חוזר בקוד ופולימורפיזם. על ידי מתן אפשרות לתפקד עם סוגים רבים, גנריות מגדילות את כוחם של ממשקים. להלן קוד המקור של הממשק הגנרי של Golang:



חֲבִילָה רָאשִׁי
יְבוּא 'fmt'
סוּג EmpAge מִמְשָׁק {
int64 | int32 | לצוף32 | לצוף64
}
func newGenericFunc [ גיל גיל ]( גיל emp_Age ) {
val := int ( emp_Age ) + 1
fmt . Println ( val )
}
func רָאשִׁי () {
fmt . Println ( 'גיל העובדים' )
היה גיל 1 int64 = 24
היה גיל 2 לצוף64 = 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'
סוּג לַעֲרוֹם [ לא כל ] [] ט
func ( רחוב * לַעֲרוֹם [ ט ]) לִדחוֹף ( פריט T ) {
רחוב = לְצַרֵף ( * רחוב , פריט )
}
func ( רחוב * לַעֲרוֹם [ ט ]) פּוֹפּ () ט {
אם רק ( * רחוב ) == 0 {
בהלה ( 'שום דבר בערימה' )
}
אינדקס := רק ( * רחוב ) - 1
פריט := ( * רחוב )[ אינדקס ]
* רחוב = ( * רחוב )[: אינדקס ]
לַחֲזוֹר פריט
}
func רָאשִׁי () {
לַעֲרוֹם := חָדָשׁ ( לַעֲרוֹם [ int ])
לַעֲרוֹם . לִדחוֹף ( 1 )
לַעֲרוֹם . לִדחוֹף ( 2 )
לַעֲרוֹם . לִדחוֹף ( 3 )
fmt . Println ( לַעֲרוֹם . פּוֹפּ ())
fmt . Println ( לַעֲרוֹם . פּוֹפּ ())
fmt . Println ( לַעֲרוֹם . פּוֹפּ ())
}

בקוד הקודם, מוגדר סוג גנרי שכותרתו 'מחסנית' המייצגת את המחסנית. מציין המיקום 'T' מאפשר לערימה להחזיק את האלמנטים מכל סוג שהוא. סוג 'מחסנית' מיושם כפרוסה של אלמנטים מסוג 'T'. כאן, שתי פונקציות נפרסות עבור סוג 'מחסנית': 'דחיפה' ו-'פופ.' הפונקציה Push() אחראית על הוספת האלמנטים לערימה. הוא לוקח פריט ארגומנט מסוג 'T' ומצרף אותו לפרוסה הבסיסית באמצעות הפונקציה append() .

בעוד שהפונקציה Pop() לוקחת את הרכיב הראשוני מהמחסנית ומחזירה אותו, היא תחילה קובעת אם המחסנית ריקה על ידי הערכת גודל הפרוסה הבסיסית. נשלחת הודעת שגיאה אם ​​נראה שהמחסנית ריקה מה שגורם לפאניקה. אחרת, הוא מאחזר את האלמנט האחרון מהפרוסה, מסיר אותו מהערימה על ידי חיתוך הפרוסה עד לרכיב השני-לאחרון, ומחזיר את הפריט שהוסר.

לאחר מכן, הערימה החדשה של מספרים שלמים נוצרת באמצעות תחביר Stack[int] בתוך הפונקציה הראשית של קוד זה. לאחר מכן, שיטת 'דחיפה' נקראת שלוש פעמים כדי להוסיף את המספרים השלמים 1, 2 ו-3 לערימה. עם זאת, שיטת 'פופ' נקראת שלוש פעמים לאחר מכן כדי לאחזר ולהדפיס את האלמנטים מהערימה.

הפלט הבא מציין שהאלמנטים מוסרים מהערימה בסדר הפוך:

דוגמה 4: שימוש במגבלות הגנריות של גולנג

Go מציעה גם אילוצים מותאמים אישית המאפשרים גמישות רבה ומגדירים דרישות ספציפיות למבנים גנריים בהתבסס על צרכי היישום שלהם. הקוד של האילוצים הגנריים המותאמים אישית מסופק בהדגמה הבאה:

חֲבִילָה רָאשִׁי
יְבוּא 'fmt'
סוּג מספרים מִמְשָׁק {
int64 | לצוף64
}
func רָאשִׁי () {
FloatValue := [] לצוף64 { 2 . 0 , 4 . 0 , 6 . 0 , 8 . 0 , 10 . 0 }
ערך שלם := [] int64 { 2 , 4 , 6 , 8 , 10 }
סכום1 := סכום גנרי ( FloatValue )
סכום2 := סכום גנרי ( ערך שלם
fmt . Println ( 'סכום של float64 :' , סכום1 )
fmt . Println ( 'סכום של int64 :' , סכום2 )

}
func סכום גנרי [ n מספרים ]( מספרים [] נ ) נ {
היה אני נ
ל _ , על אחד := טווח מספרים {
סְכוּם += על אחד
}
לַחֲזוֹר סְכוּם
}

בקוד המקור הקודם, אנו מגדירים את ממשק Numerics בשיטת 'Sum'. לאחר מכן, אנו יוצרים שני סוגים מותאמים אישית, 'FloatValue' ו-'IntegerValue', אשר מיישמים את ממשק ה-Numerics על ידי מתן שיטות ה-'Sum' המתאימות. הפונקציה genericSum מסוגלת כעת לקבל את הפרוסות מכל סוג שעונה על הממשק של Numerics. בתוך הפונקציה, אנו חוזרים על האלמנטים וקוראים לשיטת 'Sum' כדי לחשב את הסכום. לבסוף, בפונקציה הראשית, אנו יוצרים את הפרוסות של FloatValue ו-IntegerValue ומעבירים אותם לפונקציה genericSum() אשר מחשבת נכון את סכום האלמנטים בכל פרוסה.

הפלט הצפוי נראה כעת במסך הבא:

סיכום

בדקנו כמה דוגמאות מעשיות של Go גנריות הכוללות יצירת מבנה נתונים גנרי ופונקציה גנרית, הגדרת ממשק גנרי ושימוש באילוץ הסוג המותאם אישית. דוגמאות אלו מדגימות את העוצמה והגמישות שהגנריות מביאות לשפת התכנות Go. שים לב שיצירת הקוד הגנרי במהלך ההידור מבטיח את הגודל הבינארי היעיל ואת זמני ההידור.