מבוא לשפה גרובית

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

גרובי היא שפת סקריפטים דינמית עבור ה- JVM. הוא מתאסף לקידוד byt ומשתלב בצורה חלקה עם קוד Java וספריות.

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

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

2. סביבה

אם אנו רוצים להשתמש ב- Groovy בפרויקטים של Maven, עלינו להוסיף את הפרטים הבאים ל- pom.xml:

  // ... org.codehaus.gmavenplus gmavenplus-plugin 1.5 // ... org.codehaus.groovy groovy-all 2.4.10 

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

3. תכונות בסיסיות

ישנן תכונות שימושיות רבות ב- Groovy. עכשיו, בואו נסתכל על אבני הבניין הבסיסיות של השפה וכיצד היא שונה מג'אווה.

עכשיו, בואו נסתכל על אבני הבניין הבסיסיות של השפה וכיצד היא שונה מג'אווה.

3.1. הקלדה דינמית

אחת התכונות החשובות ביותר של Groovy היא התמיכה בהקלדה דינמית.

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

class Duck {String getName () {'Duck'}} class Cat {String getName () {'Cat'}} 

שתי הכיתות הללו מגדירות את אותו הדבר getName שיטה, אך היא אינה מוגדרת במפורש בחוזה.

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

ברווז ברווז = ברווז חדש () חתול חתול = חתול חדש () def list = [ברווז, חתול] list.each {obj -> println obj.getName ()}

הקוד יצטבר, ופלט הקוד לעיל יהיה:

חתול ברווז

3.2. המרה אמיתית מרומזת

כמו ב- JavaScript, גרובי מעריכה כל אובייקט לבוליאני במידת הצורך, למשל. כאשר משתמשים בו בתוך אם הצהרה או כאשר שוללים את הערך:

אם ("שלום") {...} אם (15) {...} אם (someObject) {...}

ישנם כמה כללים פשוטים לזכור לגבי המרה זו:

  • לא ריק אוספים, מערכים, מפות מעריכים עד נָכוֹן
  • שידוך עם לפחות התאמה אחת מעריכה עד נָכוֹן
  • מחטבים ו ספירות עם אלמנטים נוספים נאלצים נָכוֹן
  • לא ריק מיתרים, מיתרים GS ו CharSequences, נאלצים נָכוֹן
  • מספרים שאינם אפסים מוערכים ל נָכוֹן
  • מאולצים הפניות לאובייקטים שאינם אפסיים נָכוֹן

אם אנו רוצים להתאים אישית את המרה האמיתית המשתמעת, אנו יכולים להגדיר את שלנו asBoolean () שיטה.

3.3. יבוא

חלק מהחבילות מיובאות כברירת מחדל ואיננו צריכים לייבא אותן במפורש:

ייבא java.lang. * ייבא java.util. * ייבא java.io. * ייבא java.net. * ייבא groovy.lang. * ייבא groovy.util. * ייבא java.math.BigInteger ייבא java.math.BigDecimal

4. טרנספורמציות AST

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

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

בואו נסתכל על כמה ביאורים שכדאי לדעת.

4.1. ביאור TypeChecked

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

בואו נסתכל על הדוגמה הבאה:

class Universe {@TypeChecked int תשובה () {"ארבעים ושניים"}}

אם ננסה לקמפל קוד זה, נצפה בשגיאה הבאה:

[בדיקת סוג סטטי] - לא ניתן להחזיר ערך מסוג java.lang.String על סוג החזרת שיטה int

ה @TypeChecked ניתן ליישם ביאור על שיעורים ושיטות.

4.2. ביאור CompileStatic

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

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

5. נכסים

ב- Groovy אנו יכולים ליצור POGOs (Plain Old Groovy Objects) הפועלים באותו אופן כמו POJOs ב- Java, למרות שהם קומפקטיים יותר מכיוון גטרים וקובעים נוצרים אוטומטית עבור נכסים ציבוריים במהלך ההידור. חשוב לזכור שהם ייווצרו רק אם הם עדיין לא מוגדרים.

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

שקול אובייקט זה:

כיתת אדם {שם מחרוזת שם משפחה מחרוזת}

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

המהדר ימיר אותם לשדות פרטיים ויוסיף getName (), setName (), getLastName () ו setLasfName () שיטות. אם נגדיר את מגדיר ו גטר עבור שדה מסוים, המהדר לא ייצור שיטה ציבורית.

5.1. קיצורי דרך

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

resourceGroup.getResourcePrototype (). getName () == SERVER_TYPE_NAME resourceGroup.resourcePrototype.name == SERVER_TYPE_NAME resourcePrototype.setName ("משהו") resourcePrototype.name = "משהו"

6. מפעילים

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

6.1. הפרעה בטוחה ללא

הפופולרי ביותר הוא מפעיל ההפרשות הבטוח ללא בטל “?” מה שמאפשר לנו להימנע מ- NullPointerException בעת קריאה לשיטה או גישה לנכס של a ריק לְהִתְנַגֵד. זה שימושי במיוחד בשיחות משורשרות כאשר א ריק ערך יכול להתרחש בשלב כלשהו בשרשרת.

לדוגמא, אנו יכולים להתקשר בבטחה:

שם מחרוזת = אדם? .ארגון? .הורה? .שם

בדוגמה לעיל אם א אדם, אדם.ארגון, או ארגון.הורה הם ריק, לאחר מכן ריק מוחזר.

6.2. מפעיל אלביס

מפעיל אלביס “?:”מאפשר לנו לדחוס ביטויים טרניים. שני אלה שווים:

שם מחרוזת = person.name?: DefaultName

ו

שם מחרוזת = person.name? person.name: defaultName

שניהם מקצים את הערך של person.name למשתנה השם אם הוא גרובי נכון (במקרה זה, לא ריק ויש לו לא אפס אורך).

6.3. מפעיל חללית

מפעיל החללית “” הוא מפעיל יחסי שמתפקד כמו של Java בהשוואה ל() המשווה בין שני אובייקטים ומחזיר -1, 0 או +1 בהתאם לערכים של שני הארגומנטים.

אם הארגומנט השמאלי גדול מימין, האופרטור מחזיר 1. אם הארגומנט השמאלי קטן מימין, האופרטור מחזיר −1. אם הארגומנטים שווים, 0 מוחזר.

היתרון הגדול ביותר בשימוש במפעילי ההשוואה הוא הטיפול החלק אפסים כך ש x y לעולם לא יזרוק א NullPointerException:

println 5 null

הדוגמה לעיל תדפיס 1 כתוצאה מכך.

7. מיתרים

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

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

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

מיתרים המוגדרים עם ציטוטים כפולים תומכים באינטרפולציה באמצעות ${} תחביר:

def name = "Bill Gates" def greeting = "שלום, $ {name}"

למעשה, ניתן למקם כל ביטוי בתוך ה- ${}:

def name = "Bill Gates" def greeting = "שלום, $ {name.toUpperCase ()}"

מחרוזת עם מרכאות כפולות נקראת GString אם היא מכילה ביטוי ${}אחרת זה מישור חוּט לְהִתְנַגֵד.

הקוד שלהלן יפעל מבלי להיכשל במבחן:

def a = "שלום" טוען a.class.name == 'java.lang.String' def b = 'שלום' לטעון b.class.name == 'java.lang.String' def c = "$ {b} "טען c.class.name == 'org.codehaus.groovy.runtime.GStringImpl'

8. אוספים ומפות

בואו נסתכל על אופן הטיפול במבני נתונים בסיסיים.

8.1. רשימות

הנה כמה קוד להוסיף כמה אלמנטים למופע חדש של רשימת מערך בג'אווה:

רשימת רשימה = ArrayList חדש (); list.add ("שלום"); list.add ("עולם");

והנה אותה פעולה בגרובי:

רשימת רשימה = ['שלום', 'עולם']

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

אין תחביר נפרד ל- מַעֲרֶכֶת, אבל אנחנו יכולים להשתמש בסוג כְּפִיָה בשביל זה. או להשתמש:

הגדר ברכה = ['שלום', 'עולם']

אוֹ:

def greeting = ['שלום', 'עולם'] כסט

8.2. מַפָּה

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

def key = 'Key3' def aMap = ['Key1': 'Value 1', Key2: 'Value 2', (key): 'ערך אחר']

לאחר אתחול זה, נקבל חדש LinkedHashMap עם הערכים: מפתח 1 -> ערך 1, מפתח 2 -> ערך 2, מפתח 3 -> ערך אחר.

אנו יכולים לגשת לערכים במפה בדרכים רבות:

println aMap ['Key1'] println aMap [key] println aMap.Key1

9. מבני בקרה

9.1. תנאים: אחרת

גרובי תומך בתנאי אחרת תחביר כצפוי:

אם (...) {// ...} אחרת אם (...) {// ...} אחר {// ...} 

9.2. תנאים: מארז מתג

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

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

def x = 1.23 def result = "" switch (x) {case "foo": result = "נמצא foo" break case "bar": result + = "bar" case break [4, 5, 6, 'inList'] : result = "list" break case 12..30: result = "range" case case מספר: result = "number" case break ~ / fo * /: result = "foo regex" case break {it <0}: / / או {x <0} result = "negative" ברירת מחדל הפסקה: result = "default"} println (תוצאה)

הדוגמה שלמעלה תודפס מספר.

9.3. לולאות: בזמן

גרובי תומך בשגרה בזמן לולאות כמו שג'אווה עושה:

def x = 0 def y = 5 while (y--> 0) {x ++}

9.4. לולאות: ל

גרובי חובק את הפשטות הזו ומעודד בתוקף ל לולאות בעקבות מבנה זה:

עבור (משתנה בניתוח) {body}

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

הפלטה סביב הגוף אופציונלית אם היא מורכבת מהצהרה אחת בלבד. להלן דוגמאות לאיטרציה על פני א טווח, רשימה, מַעֲרָך, מַפָּה, ו מיתרים:

def x = 0 עבור (i ב 0..9) {x + = i} x = 0 עבור (i ב- [0, 1, 2, 3, 4]) {x + = i} מערך def = (0. .4) .toArray () x = 0 עבור (i במערך) {x + = i} def map = ['abc': 1, 'def': 2, 'xyz': 3] x = 0 for (e במפה) {x + = e.value} x = 0 עבור (v במפה.ערכים ()) {x + = v} def text = "abc" def list = [] עבור (c בטקסט) {list. הוסף (ג)}

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

ההבדל העיקרי הוא שגופו של א ל לולאה אינה סגירה, פירוש הדבר שגוף זה הוא חסם:

עבור (x ב 0..9) {println x}

ואילו גוף זה מהווה סגירה:

(0..9). כל {println it}

למרות שהם נראים דומים, הם שונים מאוד בבנייה.

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

10. טיפול בחריגים

ההבדל הגדול הוא שהטיפול בחריגים בדוקים אינו נאכף.

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

נסה {someActionThatWillThrowAnException ()} לתפוס (e) // לרשום את הודעת השגיאה, ו / או לטפל בדרך כלשהי}

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

11. סגירות

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

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

מעניין ש- Groovy יכול לנצל עד תום את תוספות ה- JDK שהוצגו כדי לתמוך במבדות, במיוחד ה- API של סטרימינג. אנחנו תמיד יכולים להשתמש בסגרים שבהם צפויים ביטויים למבדה.

בואו ניקח בחשבון את הדוגמה הבאה:

def helloWorld = {println "שלום עולם"}

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

helloWorld.call ()

Groovy מאפשר לנו להשתמש בתחביר שיחה טבעי יותר - הוא קורא ל- שִׂיחָה שיטה עבורנו:

שלום עולם()

11.1. פרמטרים

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

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

def printTheParam = {println it}

נוכל לקרוא לזה כך:

printTheParam ('שלום') printTheParam 'שלום'

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

def כוח = {int x, int y -> להחזיר Math.pow (x, y)} כוח println (2, 3)

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

def say = {what -> println what} לומר "שלום עולם"

11.2. חזרה אופציונלית

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

כיכר def = {it * it} כיכר println (4)

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

12. סיכום

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

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


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