Groovy - Kapanışlar
Kapatma, kısa ve anonim bir kod bloğudur. Normalde birkaç satırlık bir kodu kapsar. Bir yöntem, kod bloğunu bir parametre olarak bile alabilir. Doğası gereği anonimdirler.
Aşağıda basit bir kapanış örneği ve neye benzediğini görebilirsiniz.
class Example {
static void main(String[] args) {
def clos = {println "Hello World"};
clos.call();
}
}
Yukarıdaki örnekte, kod satırı - {println "Merhaba Dünya"} kapanış olarak bilinir. Bu tanımlayıcı tarafından referans verilen kod bloğu, call deyimi ile yürütülebilir.
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
Hello World
Kapanışlarda biçimsel parametreler
Kapanışlar ayrıca onları Groovy'deki yöntemler gibi daha kullanışlı hale getirmek için biçimsel parametreler içerebilir.
class Example {
static void main(String[] args) {
def clos = {param->println "Hello ${param}"};
clos.call("World");
}
}
Yukarıdaki kod örneğinde, kapamanın bir parametre almasına neden olan $ {param} kullanımına dikkat edin. Clos.call deyimi aracılığıyla closure çağrısı yaparken, artık closure'a bir parametre geçirme seçeneğimiz var.
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
Hello World
Bir sonraki çizim önceki örneği tekrarlar ve aynı sonucu verir, ancak kullanılabileceği gibi atıfta bulunulan örtük tek bir parametrenin olduğunu gösterir. Burada 'it' Groovy'de bir anahtar kelimedir.
class Example {
static void main(String[] args) {
def clos = {println "Hello ${it}"};
clos.call("World");
}
}
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
Hello World
Kapanışlar ve Değişkenler
Daha resmi olarak, kapanışlar, kapanış tanımlandığı anda değişkenlere atıfta bulunabilir. Aşağıda bunun nasıl başarılabileceğine dair bir örnek verilmiştir.
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");
}
}
Yukarıdaki örnekte, kapanışa bir parametre aktarmanın yanı sıra, str1 adında bir değişken de tanımlıyoruz. Kapanış ayrıca değişkeni parametre ile birlikte alır.
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
Hello World
Welcome World
Yöntemlerde Kapatmaları Kullanma
Kapanışlar ayrıca yöntemlerin parametreleri olarak da kullanılabilir. Groovy'de, Listeler ve koleksiyonlar gibi veri türleri için yerleşik yöntemlerin çoğu, parametre türü olarak kapanışlara sahiptir.
Aşağıdaki örnek, bir kapatmanın bir yönteme parametre olarak nasıl gönderilebileceğini gösterir.
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);
}
}
Yukarıdaki örnekte,
Bir kapanışı argüman olarak alan Display adında statik bir yöntem tanımlıyoruz.
Daha sonra ana yöntemimizde bir kapanış tanımlıyor ve bunu parametre olarak Display yöntemimize geçiriyoruz.
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
Hello World
Welcome World
Welcome Inner
Koleksiyonlarda ve Dizede Kapanışlar
Birkaç List, Map ve String yöntemi, bir kapanışı bağımsız değişken olarak kabul eder. Bu veri türlerinde kapanışların nasıl kullanılabileceğine dair bir örneğe bakalım.
Kapanışları Listelerle Kullanma
Aşağıdaki örnek, Closure'ların Listelerle nasıl kullanılabileceğini gösterir. Aşağıdaki örnekte önce basit bir değerler listesi tanımlıyoruz. Liste toplama türü daha sonra adı verilen bir işlevi tanımlar.each. Bu işlev bir parametre olarak bir kapanışı alır ve kapanışı listenin her bir öğesine uygular.
class Example {
static void main(String[] args) {
def lst = [11, 12, 13, 14];
lst.each {println it}
}
}
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
11
12
13
14
Kapatmaları Haritalar ile Kullanma
Aşağıdaki örnek, kapanışların Haritalar ile nasıl kullanılabileceğini gösterir. Aşağıdaki örnekte ilk önce basit bir anahtar değer öğeleri Haritası tanımlıyoruz. Harita koleksiyonu türü daha sonra .each adlı bir işlevi tanımlar. Bu işlev, bir kapanışı parametre olarak alır ve kapanışı haritanın her bir anahtar / değer çiftine uygular.
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}"}
}
}
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
TopicName = Maps
TopicDescription = Methods in Maps
TopicName maps to: Maps
TopicDescription maps to: Methods in Maps
Genellikle, bir koleksiyonun üyeleri arasında yineleme yapmak ve yalnızca öğe bazı kriterleri karşıladığında bazı mantıkları uygulamak isteyebiliriz. Bu, kapanışta bir koşullu ifade ile kolayca ele alınır.
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}
}
}
Yukarıdaki örnek, listedeki her bir öğenin 2'ye bölünebilir olup olmadığını kontrol etmek için kullanılan kapanışta kullanılan koşullu if (num% 2 == 0) ifadesini gösterir.
Yukarıdaki programı çalıştırdığımızda şu sonucu alacağız -
1
2
3
4
The list will only display those numbers which are divisible by 2.
2
4
Closures ile kullanılan yöntemler
Kapakların kendileri bazı yöntemler sağlar.
Sr.No. | Yöntemler ve Açıklama |
---|---|
1 | bul () Find yöntemi, bir koleksiyondaki bazı ölçütlerle eşleşen ilk değeri bulur. |
2 | hepsini bul() Kapanma koşulu ile eşleşen alıcı nesnedeki tüm değerleri bulur. |
3 | herhangi () ve her () Yöntem, bir Boolean yükleminin en az bir öğe için geçerli olup olmadığını kontrol eden bir koleksiyonun her bir öğesi aracılığıyla yinelenir. |
4 | toplamak() Toplama yöntemi, bir koleksiyon aracılığıyla yinelenir, her öğeyi transformatör olarak kapanışı kullanarak yeni bir değere dönüştürür. |