סגרים בגרובי

1. סקירה כללית

במדריך מבוא זה, נחקור את מושג הסגירות ב- Groovy, מאפיין מרכזי של שפת JVM דינמית ועוצמתית זו.

שפות רבות אחרות, כולל Javascript ו- Python, תומכות במושג הסגירות. עם זאת, המאפיינים והתפקוד של סגירות משתנים משפה לשפה.

ניגע בהיבטים מרכזיים של סגירות גרובי ונציג דוגמאות לאופן השימוש בהן בדרך.

2. מהי סגירה?

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

בנוסף, סגירה עשויה לגשת למשתנים המקיפים מחוץ לתחום שלה ולהשתמש בהם - יחד עם המשתנים המקומיים שלה - במהלך הביצוע.

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

3. הצהרת סגירה

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

3.1. הצהרה בסיסית

def printWelcome = {println "ברוך הבא לסגירות!" }

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

def print = {name -> println name}

הנה, הסגירה הדפס לוקח פרמטר אחד - שֵׁם - ומדפיס אותו כשהוא מופעל.

מאז ההגדרה של סגירה נראית דומה לשיטהבואו נשווה אותם:

def formatToLowerCase (שם) {return name.toLowerCase ()} def formatToLowerCaseClosure = {name -> return name.toLowerCase ()} 

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

3.2. ביצוע

אנו יכולים לבצע סגירה בשתי דרכים - אנו יכולים להפעיל אותה כמו בכל שיטה אחרת, או שאנחנו יכולים להשתמש שִׂיחָה שיטה.

למשל, כשיטה רגילה:

הדפס ("שלום! סגירה") פורמט ToLowerCaseClosure ("שלום! סגירה") 

וביצוע עם שִׂיחָה שיטה:

print.call ("שלום! סגירה") formatToLowerCaseClosure.call ("שלום! סגירה")

4. פרמטרים

הפרמטרים של סגירת גרובי דומים לאלה של שיטות רגילות.

4.1. פרמטר מרומז

אנו יכולים להגדיר סגירה unary ללא פרמטר בגלל כאשר לא מוגדרים פרמטרים, גרובי מניח פרמטר מרומז בשם "זה":

def greet = {return "Hello! $ {it}"} assert greet ("Alex") == "Hello! Alex"

4.2. פרמטרים מרובים

הנה סגירה שלוקחת שני פרמטרים ומחזירה את התוצאה של הכפלתם:

def להכפיל = {x, y -> להחזיר x * y} להכפיל (2, 4) == 8

4.3. סוגי פרמטרים

בדוגמאות עד כה לא היה שום סוג המסופק עם הפרמטרים שלנו. אנו יכולים גם להגדיר את סוג הפרמטרים לסגירה. למשל, בואו נכתוב מחדש את ה- לְהַכפִּיל שיטה לשקול פעולות אחרות:

def לחשב = {int x, int y, מחרוזת -> def result = 0 מתג (פעולה) {case "ADD": result = x + y case case "SUB": result = xy break case "MUL": result = x * y case case "DIV": result = x / y break} return return} assert calculate (12, 4, "ADD") == 16 assert חושב (43, 8, "DIV") == 5.375

4.4. Varargs

אנו יכולים להכריז על מספר משתנה של טיעונים בסגירות, בדומה לשיטות רגילות. לדוגמה:

def addAll = {int ... args -> return args.sum ()} assert addAll (12, 10, 14) == 36

5. סגירה כטיעון

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

בואו נדון במקרה שימוש פשוט: חישוב נפח הנתונים הרגילים.

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

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

נפח def (סגירת שטח מחשבון, אינט ... מידות) {if (dimensions.size () == 3) {return areaCalculator (מידות [0], מידות [1]) * מידות [2]} אחרת אם (מידות.גודל () == 2) {return areaCalculator (מידות [0]) * מידות [1]} אחרת אם (dimensions.size () == 1) {אזור חזרה מחשבון (מידות [0]) * מידות [0]}} טוענים נפח ({l, b -> החזר l * b}, 12, 6, 10) == 720 

בואו למצוא נפח של חרוט באותה שיטה:

טען נפח ({רדיוס -> החזר Math.PI * רדיוס * רדיוס / 3}, 5, 10) == Math.PI * 250

6. סגירות מקוננות

אנו יכולים להצהיר ולהפעיל סגירות בתוך סגירה.

לדוגמא, בואו נוסיף יכולת רישום לדברים שכבר נדונו לחשב סגירת מעגל:

def לחשב = {int x, int y, פעולת מחרוזת -> def log = {println "ביצוע $ it"} def result = 0 מתג (פעולה) {מקרה "ADD": יומן ("Addition") תוצאה = x + y שבירת מקרה "SUB": יומן ("חיסור") תוצאה = xy שבר מקרה "MUL": יומן ("כפל") תוצאה = x * y מקרה שבירה "DIV": יומן ("חלוקה") תוצאה = x / y הפסקה } החזר תוצאה}

7. הערכה עצלה של מיתרים

קִצבִּי חוּטבדרך כלל מעריכים ומערכים אותם בזמן היצירה. לדוגמה:

def name = "Samwell" def welcomeMsg = "ברוך הבא! $ name" לטעון welcomeMsg == "ברוך הבא! Samwell"

גם אם נשנה את הערך של ה- שֵׁם משתנה, ה- ברוך הבא לא הולך להשתנות:

שם = "טארלי" טוענים בברכה MSg! = "ברוך הבא! טארלי"

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

def fullName = "טארלי שמשון" def greetStr = "שלום! $ {-> fullName}" טען greetStr == "שלום! טארלי שמשון"

רק הפעם, שינוי המשתנה משפיע גם על ערך המחרוזת האינטרפולציה:

fullName = "ג'ון סמית" טוען שלוםStr == "שלום! ג'ון סמית"

8. סגירות באוספים

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

def list = [10, 11, 12, 13, 14, true, false, "BUNTHER"] list.each {println it} assert [13, 14] == list.findAll {it example of Integer && it> = 13}

לעתים קרובות, על סמך קריטריון כלשהו, ​​ייתכן שנצטרך ליצור רשימה ממפה. לדוגמה:

def map = [1:10, 2:30, 4: 5] לטעון [10, 60, 20] == map.collect {it.key * it.value} 

9. סגירות לעומת שיטות

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

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

  • אנחנו יכולים להעביר א סגירת מעגל כטיעון לשיטה
  • סגירות אוניות יכולות להשתמש במשתמע זה פָּרָמֶטֶר
  • אנחנו יכולים להקצות א סגירת מעגל למשתנה ולבצע אותו מאוחר יותר, אם כשיטה או עם שִׂיחָה
  • גרובי קובע את סוג ההחזר של הסגירות בזמן הריצה
  • אנו יכולים להצהיר ולהפעיל סגירות בתוך סגירה
  • סגירות תמיד מחזירות ערך

לפיכך, לסגירות יש יתרונות על פני שיטות רגילות והן מאפיין רב עוצמה של גרובי.

10. מסקנה

במאמר זה ראינו כיצד ליצור סגירות בגרובי וחקרנו כיצד משתמשים בהם.

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

כמו תמיד, בדיקות הקוד ומבחני היחידות ממאמר זה זמינים ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found