ביטויים למבדה בקוטלין

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

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

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

2. הגדרת למבדה

כפי שנראה, Kotlin Lambdas דומים מאוד ל- Java Lambdas. תוכל למצוא מידע נוסף על אופן העבודה עם Java Lambdas וכמה שיטות עבודה מומלצות כאן.

כדי להגדיר למבדה, עלינו לעמוד בתחביר:

val lambdaName: Type = {argumentList -> codeBody}

החלק היחיד של למבדה שאינו אופציונלי הוא codeBody.

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

סוג הפקודה האחרונה בתוך בלוק למבדה הוא הסוג שהוחזר.

2.1. סוג הסקה

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

כתיבת למבדה המייצרת את ריבוע המספר תהיה כתובה כמו:

ריבוע ואל = {מספר: Int -> מספר * מספר} ואל תשע = ריבוע (3)

קוטלין יעריך את הדוגמה לעיל כדי להיות פונקציה שלוקחת אחת Int ומחזיר an Int:(Int) -> Int

אם היינו רוצים ליצור למבדה המכפילה את מספרי הארגומנטים היחידים שלה ב- 100 ואז מחזירים את הערך כ- חוּט:

val magnitude100String = {input: Int -> magnitude val = input * 100 magnitude.toString ()} 

קוטלין יבין שלמבדה זו היא מסוג (Int) -> מחרוזת.

2.2. הצהרת סוג

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

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

val that: Int -> Int = {three -> three}
val more: (String, Int) -> String = {str, int -> str + int}
val no Return: Int -> Unit = {num -> println (num)}

אנו יכולים להשתמש במבשמות כהרחבות כיתות:

val אחר: String. (Int) -> String = {this + it}

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

כדי להשתמש בתבנית זו מתוך חוּט אנו קוראים Type.lambdaName (ארגומנטים)אז לקרוא לדוגמא 'אחרת' שלנו:

fun extendString (arg: String, num: Int): String {val another: String. (Int) -> String = {this + it} return arg.another (num)}

2.3. חוזרים מלמבה

הביטוי הסופי הוא הערך שיוחזר לאחר ביצוע למבדה:

val calculatorGrade = {grade: Int -> when (grade) {in 0..40 -> "Fail" in 41..70 -> "Pass" in 71..100 -> "הבחנה" אחר -> false}}

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

val calculatorGrade = fun (דרגה: Int): מחרוזת {if (דרגה 100) {להחזיר "שגיאה"} אחרת אם (דרגה <40) {להחזיר "נכשל"} אחרת אם (דרגה <70) {החזר "לעבור"} "הבחנה" }

3. זה

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

אנו נבצע את אותו הדבר לכל אחד שיטה במערך הבא של שקעים:

מערך val = arrayOf (1, 2, 3, 4, 5, 6)

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

כְּתִיבָה רְגִילָה:

array.forEach {item -> println (item * 4)}

קַצרָנוּת:

array.forEach {println (it * 4)}

4. יישום למבדות

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

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

כיף להעלות למבדה (למבדה: (כפול) -> בוליאני): בוליאני {לחזור למבדה (4.329)}

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

4.1. משתנה של אובייקט למבדה

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

@Test fun whenPassingALambdaObject_thenCallTriggerLambda () {val lambda = {arg: Double -> arg == 4.329} val result = invokeLambda (lambda) assertTrue (result)}

4.2. למבדה מילולית

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

לבדוק כיף כאשר עובר ALambdaLiteral_thenCallTriggerLambda () {val result = invokeLambda ({true}) assertTrue (result)}

4.3. למבדה ממש מחוץ לסוגרים

דפוס נוסף עבור מילולי מילבדה שעודדו על ידי JetBrains - הוא להעביר את הלמדה כטיעון האחרון לשיטה ולהציב את הלמבה מחוץ לקריאת השיטה:

@Test fun whenPassingALambdaLiteralOutsideBrackets_thenCallTriggerLambda () {val result = invokeLambda {arg -> arg.isNaN ()} assertFalse (result)}

4.4. הפניות לשיטה

לבסוף, יש לנו אפשרות להשתמש בהפניות לשיטה. אלה הפניות לשיטות קיימות.

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

@Test fun whenPassingAFunctionReference_thenCallTriggerLambda () {val reference = Double :: isFinite val result = invokeLambda (reference) assertTrue (result)}

5. Kotlin Lambda בג'אווה

Kotlin משתמש בממשקי פונקציות שנוצרו כדי לבצע אינטראקציה עם Java. הם קיימים בקוד המקור של קוטלין כאן.

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

המבנה של א פוּנקצִיָה הגנריות של הממשק היא שהמספר ומייצג את מספר הארגומנטים לממדה, ואז מספר המחלקות יהיה הארגומנט סוגים לפי הסדר.

הטיעון הגנרי הסופי הוא סוג ההחזרה:

יבוא kotlin.jvm.functions. * ממשק ציבורי פונקציה 1: פונקציה {הנעה של מפעיל ציבורי (p1: P1): R}

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

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

יבוא kotlin.Unit; יבוא kotlin.jvm.functions.Function1; ... פונקציה חדשה 1 () {@Override יחידה ציבורית להפעיל (לקוח c) {AnalyticsManager.trackFacebookLogin (c.getCreated ()); החזר אפס; }} 

בעת שימוש ב- Java8 אנו משתמשים ב- Java lambda במקום ב- פוּנקצִיָה כיתה אנונימית:

@Test בטל שניתןJava8_whenUsingLambda_thenReturnLambdaResult () {assertTrue (LambdaKt.takeLambda (c -> c> = 0)); }

6. שיעורים פנימיים אנונימיים

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

6.1. ביטוי אובייקט

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

כדי להדגים זאת, ניקח ממשק פשוט ושיעור שלוקח יישום של ממשק זה ומכנה את השיטות תלויות ב- בוליאני טַעֲנָה:

מעבד מחלקה {ממשק ActionCallback {fun success (): כישלון מחרוזת (): String} fun performEvent (החלטה: בוליאני, callback: ActionCallback): מחרוזת {return אם (החלטה) {callback.success ()} אחר {callback.failure ()}}}

כעת כדי לספק מעמד פנימי אנונימי, עלינו להשתמש בתחביר "האובייקט":

@Test fun givenMultipleMethods_whenCallingAnonymousFunction_thenTriggerSuccess () {val result = מעבד (). PerformEvent (true, object: Processor.ActionCallback {override fun success () = "הצלחה" לעקוף כישלון כיף () = "Failure"}) assertEquals ("הצלחה") תוצאה)}

6.2. ביטוי למבדה

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

  1. השיעור הוא יישום של ממשק Java (לא ממש של Kotlin)
  2. הממשק חייב להכיל מקסימום

אם שני התנאים הללו מתקיימים, אנו עשויים להשתמש בביטוי למבדה במקום.

הלמבדה עצמה תיקח טיעונים רבים ככל שהשיטה היחידה של הממשק עושה.

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

val list = ArrayList (2) list.stream () .forEach ({i -> println (i)})

7. סיכום

על אף שהם דומים מבחינה תחבירית, lambdas של קוטלין וג'אווה הם מאפיינים שונים לחלוטין. בעת מיקוד ל- Java 6, על קוטלין להפוך את הלמבדות שלה למבנה שניתן להשתמש בו בתוך JVM 1.6.

למרות זאת, השיטות המומלצות של Java 8 lambdas עדיין חלות.

למידע נוסף על שיטות עבודה מומלצות למבדה.

קטעי קוד, כמו תמיד, ניתן למצוא באתר GitHub.


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