tags:

views:

209

answers:

2

Dear All,

I have the following code for building a cache using google collections:

val cache = new MapMaker().softValues().expiration(30,
TimeUnit.DAYS).makeComputingMap(
   new com.google.common.base.Function[String,Int] {
      def apply(key:String):Int ={
        1
     }
   })

And I am getting the following error message:

error: type mismatch;
 found   : java.lang.Object with
com.google.common.base.Function[java.lang.String,Int]{ ... }
 required: com.google.common.base.Function[?, ?]
   new com.google.common.base.Function[String,Int] {
   ^

I am wondering why the types don't match ?

The actual code is:

import com.google.common.collect.MapMaker
trait DataCache[V] {
  private val cache = new MapMaker().softValues().makeComputingMap(
    new com.google.common.base.Function[String,V] {
      def apply(key:String):V = null.asInstanceOf[V]
    })
  def get(key:String):V = cache.get(key)
}

Kind regards, Ali

PS - I am using google-collections v1

+1  A: 

Does the following works?

new com.google.common.base.Function[_,_] {

If that doesn't work, you may wish to keep the declaration as it is right now, and then add a : com.google.common.base.Function[_, _] after it, like this:

val cache = new MapMaker().softValues().expiration(30,
TimeUnit.DAYS).makeComputingMap(
   new com.google.common.base.Function[String,Int] {
      def apply(key:String):Int ={
        1
     }
   }: com.google.common.base.Function[_, _])

I have heard that some Google stuff use raw types, which are rather hard to integrate well with Scala. And, in fact, should be banished back to hell, where they came from, but that's just imho.

Also, if you could compile that with -explaintypes, we may get a better notion of what is failing.

Daniel
Doesn't work, now I get this error:class type required but com.google.common.base.Function[_, _] found new com.google.common.base.Function[_,_] I also tried -explaintypes, actually the output is really hard to understand:java.lang.Object with com.google.common.base.Function[_, _] < com.google.common.base.Function[(some other)_$7(in template $anon),(some other)_$8(in template $anon)]? java.lang.Object < com.google.common.base.Function[(some other)_$7(in template $anon),(some other)_$8(in template $anon)]? ...
Ali
@Ali: it seems you only tried the first suggestion. I pasted the full code for the second suggestion now. Also, please add the output of `-explaintypes` to your question.
Daniel
@Daniel, Actually the output is pretty big, I added the actual code which one can just copy paste to reproduce the error message. Please let me know if there is anything else I shall provide.
Ali
@Ali: that would requiring getting the required libraries. Don't worry about the error being big, S.O. will show it in a window with a scrollbar past a certain amount of lines.
Daniel
@Ali: nevermind, saw Paul's answer, he rulez.
Daniel
+5  A: 

You need to supply type parameters to the final method call. You are going through the raw type interface and scala cannot reconstruct the type information.

val cache = new MapMaker().softValues().expiration(30,
TimeUnit.DAYS).makeComputingMap[String, Int](
   new com.google.common.base.Function[String,Int] {
      def apply(key:String):Int ={
        1
     }
   })
extempore