
- Groovy 教程
- Groovy - 首頁
- Groovy - 概述
- Groovy - 環境配置
- Groovy - 基本語法
- Groovy - 資料型別
- Groovy - 變數
- Groovy - 運算子
- Groovy - 迴圈
- Groovy - 決策
- Groovy - 方法
- Groovy - 檔案I/O
- Groovy - 可選值
- Groovy - 數字
- Groovy - 字串
- Groovy - 範圍
- Groovy - 列表
- Groovy - 對映
- Groovy - 日期和時間
- Groovy - 正則表示式
- Groovy - 異常處理
- Groovy - 面向物件
- Groovy - 泛型
- Groovy - 特性 (Traits)
- Groovy - 閉包
- Groovy - 註解
- Groovy - XML
- Groovy - JMX
- Groovy - JSON
- Groovy - DSL
- Groovy - 資料庫
- Groovy - 構造器
- Groovy - 命令列
- Groovy - 單元測試
- Groovy - 模板引擎
- Groovy - 元物件程式設計
- Groovy 有用資源
- Groovy - 快速指南
- Groovy - 有用資源
- Groovy - 討論
Groovy - 閉包
閉包是一個簡短的匿名程式碼塊。它通常只包含幾行程式碼。方法甚至可以將程式碼塊作為引數。它們本質上是匿名的。
下面是一個簡單的閉包示例及其外觀。
class Example { static void main(String[] args) { def clos = {println "Hello World"}; clos.call(); } }
在上面的示例中,程式碼行 - {println "Hello World"} 被稱為閉包。可以透過呼叫語句執行此識別符號引用的程式碼塊。
執行上述程式後,我們將得到以下結果:
Hello World
閉包中的形式引數
閉包也可以包含形式引數,使其更像Groovy中的方法一樣有用。
class Example { static void main(String[] args) { def clos = {param->println "Hello ${param}"}; clos.call("World"); } }
在上面的程式碼示例中,請注意${param}的使用,它使閉包能夠接受引數。當透過clos.call語句呼叫閉包時,我們現在可以選擇向閉包傳遞引數。
執行上述程式後,我們將得到以下結果:
Hello World
下一個示例重複了前面的示例併產生相同的結果,但它顯示可以使用稱為it的隱式單引數。“it”是Groovy中的關鍵字。
class Example { static void main(String[] args) { def clos = {println "Hello ${it}"}; clos.call("World"); } }
執行上述程式後,我們將得到以下結果:
Hello World
閉包和變數
更正式地說,閉包可以引用定義閉包時的變數。以下是如何實現此目的的示例。
class Example { static void main(String[] args) { def str1 = "Hello"; def clos = {param -> println "${str1} ${param}"} clos.call("World"); // We are now changing the value of the String str1 which is referenced in the closure str1 = "Welcome"; clos.call("World"); } }
在上面的示例中,除了向閉包傳遞引數外,我們還定義了一個名為str1的變數。閉包也包含該變數和引數。
執行上述程式後,我們將得到以下結果:
Hello World Welcome World
在方法中使用閉包
閉包也可以用作方法的引數。在Groovy中,許多列表和集合的內建方法都將閉包作為引數型別。
以下示例顯示如何將閉包作為引數傳送到方法。
class Example { def static Display(clo) { // This time the $param parameter gets replaced by the string "Inner" clo.call("Inner"); } static void main(String[] args) { def str1 = "Hello"; def clos = { param -> println "${str1} ${param}" } clos.call("World"); // We are now changing the value of the String str1 which is referenced in the closure str1 = "Welcome"; clos.call("World"); // Passing our closure to a method Example.Display(clos); } }
在上面的例子中:
我們定義了一個名為Display的靜態方法,該方法接受閉包作為引數。
然後我們在主方法中定義一個閉包,並將其作為引數傳遞給我們的Display方法。
執行上述程式後,我們將得到以下結果:
Hello World Welcome World Welcome Inner
集合和字串中的閉包
許多List、Map和String方法都接受閉包作為引數。讓我們看看如何在這些資料型別中使用閉包的示例。
使用閉包與列表
以下示例顯示如何將閉包與列表一起使用。在下面的示例中,我們首先定義一個簡單的值列表。然後,列表集合型別定義一個名為.each的函式。此函式接受閉包作為引數,並將閉包應用於列表的每個元素。
class Example { static void main(String[] args) { def lst = [11, 12, 13, 14]; lst.each {println it} } }
執行上述程式後,我們將得到以下結果:
11 12 13 14
使用閉包與對映
以下示例顯示如何將閉包與對映一起使用。在下面的示例中,我們首先定義一個簡單的鍵值對對映。對映集合型別然後定義一個名為.each的函式。此函式接受閉包作為引數,並將閉包應用於對映的每個鍵值對。
class Example { static void main(String[] args) { def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"] mp.each {println it} mp.each {println "${it.key} maps to: ${it.value}"} } }
執行上述程式後,我們將得到以下結果:
TopicName = Maps TopicDescription = Methods in Maps TopicName maps to: Maps TopicDescription maps to: Methods in Maps
通常,我們可能希望遍歷集合的成員,並且僅當元素滿足某些條件時才應用某些邏輯。這可以透過閉包中的條件語句輕鬆處理。
class Example { static void main(String[] args) { def lst = [1,2,3,4]; lst.each {println it} println("The list will only display those numbers which are divisible by 2") lst.each{num -> if(num % 2 == 0) println num} } }
上面的示例顯示了在閉包中使用的條件if(num % 2 == 0)表示式,用於檢查列表中的每個專案是否能被2整除。
執行上述程式後,我們將得到以下結果:
1 2 3 4 The list will only display those numbers which are divisible by 2. 2 4
與閉包一起使用的方法
閉包本身提供了一些方法。
序號 | 方法和描述 |
---|---|
1 | find()
find方法查詢集合中第一個匹配某些條件的值。 |
2 | findAll()
它查詢接收物件中所有匹配閉包條件的值。 |
3 | any() & every()
any方法迭代集合的每個元素,檢查布林謂詞對至少一個元素是否有效。 |
4 | collect()
collect方法迭代集合,使用閉包作為轉換器將每個元素轉換為新值。 |