【问题标题】:Error while passing a tuple to a generic method将元组传递给泛型方法时出错
【发布时间】:2017-03-02 13:56:01
【问题描述】:

这是一个记忆/缓存中间结果的函数:

 def memoize[I, O](f: I => O) = new scala.collection.mutable.HashMap[I, O]() {
   override def apply(key: I): O = getOrElseUpdate(key, f(key))    
 }

这适用于下面的代码,

val double: Int=>Int = memoize {
    _*2
}

但是,当我尝试使用元组作为输入参数(I)时,它显示编译时错误,

val isGivenNumIsHead:(List[Int], Int) => Boolean = memoize {
  case (Nil, _) => false
  case (a:: as, n) => a == n
}

编译时错误是:

mutable.HashMap[Nothing, Boolean] {def apply(key: Nothing): Boolean} 类型的表达式不符合预期类型 (List[Int], Int) => Boolean

这与擦除有关吗?

我该如何解决?

【问题讨论】:

  • 我很困惑。 memoize 返回一个 HashMap[O, I],但您想返回一个函数类型:(List[Int], Int]) => Boolean?

标签: scala generics


【解决方案1】:

我假设您想使用元组作为 HashMap 中的键。考虑到这一点,这里是解释。

memoize 的实际返回类型是 scala.collection.mutable.HashMap[_,_] 。这被分配给double 类型为Int => IntFunction1[Int,Int](一个接受整数并给出整数的函数)。编译器不会抛出错误,因为mutable.HashMap 扩展了scala.collection.mutable.MapLike,而scala.collection.MapLike 又扩展了scala.PartialFunction[A, B],而scala.PartialFunction[A, B] 又扩展了scala.Function1[A, B]。因此没有编译错误。

另一方面,接受一个参数并返回一个值的函数的语法是val functionName : A => B = a => {return b},或者可以写成val function : (A) => B = a => {return b}val function: (A => B) = a => {return b}。您使用了第二种方法。在这种情况下,A 的值应该是单一类型。您使用了List[Int],Int,它不是单一类型。请注意,我故意删除了括号。因此,为了将其作为单一类型并将其作为元组传递,您必须再使用一组括号。正确的语法是

val isGivenNumIsHead:((List[Int], Int)) => Boolean = memoize {
  case (Nil, _) => false
  case (a:: as, n) => a == n
}

注意使用附加括号使其成为元组。

【讨论】:

  • 非常感谢!感谢您详细而精彩的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多