从scala使用Function <A,R> java接口的流畅方法?

fic*_*udd 5 java interop functional-programming scala

在工作中,大多数人使用Java,而我正在使用Scala.我们决定在一个用Java编写的库中收集一些常用的类.现在我想在库中添加一些伪函数式编程,看看下面的内容:

Java的:

public interface Func<A, R> {
    public R f(a A);
}

public AClass {
    public <R> ArrayList<R> myMethod(
                             Func<String, R> func
    ) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在java中的用法:

AClass ac = new AClass();
ArrayList<String> al = ac.myMethod(
                            new Func<String, String> (
                                public String f(String s) {
                                    return s + "!";
                                }
                            })
Run Code Online (Sandbox Code Playgroud)

上面并没有完全退出(从scala的角度来看,实际上更像是令人生畏).有没有办法召唤一些scala魔法,以便能够在scala中执行以下操作:

var ac = new ACLass
var al = ac.myMethod(str => str + "!")             // alternative 1
al = ac.myMethod { case: str:String => str + "!" } // alternative 2
Run Code Online (Sandbox Code Playgroud)

我搞砸了一段时间,但无法解决问题= P.

par*_*tic 14

使用隐式转换:

object FuncConversions {
  implicit def func2function[A,R]( fn: (A) => R ) =
    new Func[A,R] {
      def f(a: A) = fn(a)
    }
}
Run Code Online (Sandbox Code Playgroud)

不要忘记在您的范围中导入转换:

import FuncConversions._
Run Code Online (Sandbox Code Playgroud)

您也可以实现相反的转换.


huy*_*hjl 6

扩大范式答案.这是你如何找出隐含的.当类型不检查时,隐式转换会发挥作用.发生这种情况时,编译器将搜索要使用的隐式转换,以便类型匹配.

在清理你的例子后,在REPL中,编译器会显示:

scala> ac.myMethod((s:String) => s + "!")
<console>:9: error: type mismatch;
 found   : String => java.lang.String
 required: Func[java.lang.String,?]
              ac.myMethod((s:String) => s + "!")
Run Code Online (Sandbox Code Playgroud)

所以编译器告诉你它找到了(String) => (String)但需要一个Func[String, ?].因此,您希望在找到的类型和所需类型之间提供隐式转换.签名应该是这样的:

implicit def fun2Func(fun: (String) => String): Func[String,String]
Run Code Online (Sandbox Code Playgroud)

然后,下一步是认识到隐式转换可以用类型A和R推广.

在旁注中,我想知道你是否会更好地使用http://code.google.com/p/guava-libraries/这样的架子.