简体   繁体   English

Scala 错误:缺少扩展函数的参数类型

[英]Scala error: missing parameter type for expanded function

I am trying to write a query library for Scala.我正在尝试为 Scala 编写一个查询库。 Here is the code so far:这是到目前为止的代码:

class Query[TElement](source: Traversable[TElement]) {
    def join[TOther](other: Traversable[TOther]) = new {
        def on[TKey](keySelector1: TElement => TKey) = new {
            def equals(keySelector2: TOther => TKey) = new {
                def into[TResult](resultSelector: (TElement, TOther) => TResult): Query[TResult] = {
                    val map = source.map(e => (keySelector1(e), e)).toMap
                    val results = other
                        .map(e => (keySelector2(e), e))
                        .filter(p => map.contains(p._1))
                        .map(p => (map(p._1), p._2))
                        .map(p => resultSelector(p._1, p._2))
                    new Query[TResult](results)
                }
            }
        }
    }
}

object Query {
    def from[TElement](source: Traversable[TElement]): Query[TElement] = {
        new Query[TElement](source)
    }
}

... ...

val results = Query.from(users)
    .join(accounts).on(_.userId).equals(_.ownerUserId).into((_, _))

I get the following error when I go to compile:编译时出现以下错误:

error: missing parameter type for expanded function ((x$2) => x$2.ownerUserId)

I am a little confused why I would get this error on the non-generic function equals .我有点困惑为什么我会在非泛型函数equals上得到这个错误。 Its generic parameters come from the outer scope, I'd think.我认为它的通用参数来自外部范围。 I know to fix it I have to explicitly say what the parameter type is by writing (a: Account) => a.ownerUserId .我知道要修复它,我必须通过写入(a: Account) => a.ownerUserId来明确说明参数类型是什么。 However, I am trying to make it a pretty fluent library, and this is making it messy.但是,我试图使它成为一个非常流畅的库,这使它变得混乱。

The problem is quite simple.问题很简单。 There is an ambiguity with the existing method equals that is inherited from Any .Any继承的现有方法equals存在歧义。 Simple example:简单的例子:

scala> class X[A, B] { def equals(f: A => B) = f }
defined class X

scala> val x = new X[Int, String]
x: X[Int,String] = X@52d455b8

scala> x.equals((x: Int) => x.toString)
res0: Int => String = <function1>

scala> x.equals((x: String) => x.toString) // uh-oh
res1: Boolean = false

As one can see in the last example, when the wrong function type is passed, the compiler has to choose def equals(Any): Boolean .正如在上一个示例中所见,当传递错误的函数类型时,编译器必须选择def equals(Any): Boolean When you don't specify any type, the compiler has to infer one, which it can't do in the example.当您不指定任何类型时,编译器必须推断出一个类型,而在示例中无法做到这一点。

Simply rename your method to something else and the problem is gone.只需将您的方法重命名为其他名称,问题就消失了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM