2016-11-03 89 views
5

w tej klasie Java:Metoda Referencje jak w Java 8 Scala

import java.util.function.*; 

public class T { 

    public String func(String a) { 
     System.out.println("There we go: " + a); 
     return a; 
     } 

    public static void main(String... args) { 
     final Supplier<T> c = T::new; 
     final BiFunction<T, String, String> f = T::func; 

     final T t = c.get(); 
     final String v = f.apply(t, "something"); 

     System.out.println(v); 
    } 

} 

mogę uzyskać odniesienie metoda konstruktora T i do metody instancji func.

Czy istnieje sposób, aby zrobić to samo w Scala, czyli dostać

val c:() => T = ??? // default constructor of T as function 
val f: (T, String) => String = ??? // instance method func of T as function 

bez zawijania je tak:

val c:() => T =() => new T 
val f: (T, String) => String = (t, arg) => t.func(arg) 

czyli jest jakiś sposób, który jest tak elegancki jak Java 8 sposób uzyskać odniesienia do konstruktora i metody instancji, aby uzyskać funkcje scala dla tych rzeczy?

+0

Nie, nie możesz tego zrobić dokładnie. Zwykle nie musisz tego robić. Może być bardziej pomocny, jeśli wyjaśnisz, co naprawdę chcesz osiągnąć dzięki temu ... – Dima

+0

W powyższym przykładzie wyrażenie "final Supplier c = T :: new;" jest semantycznie równoważne "val c: () => T =() => nowy T'. Nie jestem pewien, czego chciałbyś uniknąć. – maasg

Odpowiedz

1

Dokładnie tak, jak robisz to w java 8, nie możesz. Dla konstruktora klasy myślę, że nie ma sposobu, aby to zrobić, z wyjątkiem tego, jak to zrobiłeś.

Dla funkcji można używać symboli zastępczych, które są "czystsze" w mojej opinii.

var t = new T() 
var func = t.func _ 
func("a") 

Jeśli używasz case class następnie można użyć metody apply.

case class C(a: String) 
var d = C.apply _ 
d("c") 

Można użyć funkcji apply dla normalnych klasach też, ale trzeba go realizować siebie. W przypadku klas przypadków są one realizowane automatycznie.

2

Najpierw rzućmy okiem na dosłownym tłumaczeniu kodu Java Scala:

class T { 
    def func(a:String) : String = { 
    println(s"There we go: $a") 
    a 
    } 
} 
object T { 
    def main(args: Array[String]) = { 
    val supplier =() => new T 
    val f = (t:T) => t.func _ 

    val t = supplier() 
    val v = f(t)("something") 
    println(v) 
    } 
} 

w Scala, funkcje są obywatelami pierwszej klasy, a więc nie ma potrzeby, aby mieć szczególne konstrukcje dla „rzeczy, które generują ”, podobnie jak Java Supplier, jak to jest modelowany jako funkcję: f:() => T (samo odnosi się do jego odpowiednikiem, Consumer jak f: T =>())

po prostu powiedział, że funkcje są obywatelami pierwszej klasy, więc zobaczymy wersję powyższego używając tego paradygmatu:

object Tfunc { 
    // let's remove the println side-effect from a function. 
    val func: String => String = a => s"There we go: $a" 

    def main(args: Array[String]) = { 
    println(func("something")) 
    } 
} 

W Scala, nie ma odpowiednika w celu uzyskania odniesienie konstruktora, ale jeśli celem jest wykorzystanie podejścia funkcjonalnego, Scala object s oferują prostą konstrukcję, aby utrzymać funkcje i nie wymagają, aby być instancja.