2016-08-31 97 views
2

我想要一个具有静态可用的函数的类(它由一个特征收缩)。然后我想要一个类型参数化的方法,它接受这样的类型作为它的类型参数,并访问合同化的静态函数。 (是的,我知道术语static是Java而不是Scala,但你知道我的意思。)伴侣类型的Scala类型约束

我知道在Scala中有一个静态函数的唯一方法是让伴随对象扩展特征。然而,这样做有两个问题:

  1. 我不知道如何约束类型参数,使它的伴侣对象扩展了一些特质。
  2. 我不知道我将如何访问静态方法,该类实际上是与其伴侣对象不同的类型。

这可能是完全关闭,但有点是我想要做的是:

MyTrait { 
    def MyFunction() : Any //some function 
} 

case class MyClass(i: Int) 

object MyClass extends MyTrait { 
    def MyFunction() = {/*do stuff*/} 
} 

//need the type as a class not an object because I need it for a higher order function like this 
def SomeFunctionHigherOrderFunction[T /*constrain T such that the companion object of T <: MyTrait*/](someFunc : Function1[T, Any]) : Unit { 
    val someStuff = T.MyFunction() 
    /*use someStuff in here*/ 
} 

SomeFunctionHigherOrderFunction[T](/*provide a Function1[T, Any]*/); 

正确的解决方案的任何想法或要对这个问题的一些更好的方法?

在此先感谢!

+1

你必须使用它你的代码中有些拼写错误。 [确保我们可以编译你给我们的例子!](http://sscce.org/) –

回答

0

没有办法做到这一点。你可以采取的一种方法是通过implicits传递方法(这也被称为类型类方法)。你需要通过T参数化你的特质(即使你不使用它,T被用来解决右边的隐含问题)。

trait MyTrait[T] { 
    def MyFunction() : Any //some function (usually you want to use `T` somehow) 
} 

然后,您声明伴随对象是隐式的。事情是这样的

implicit object MyClass extends MyTrait[MyClass] { 
    def MyFunction = ... 
} 

或者,如果你没有什么该对象一样,你甚至可以这样做只是在线:

implicit val myTraitMyClass: MyTrait[MyClass] = new MyTrait[MyClass] { 
    def MyFunction = ... 
} 

,并通过

def SomeHigherOrderFunction[T](someFunc : Function1[T, Any])(implicit o: MyTrait[T]): Unit { 
    val someStuff = o.MyFunction() 
    /*use someStuff in here*/ 
} 
+0

这个解决方案非常棒!唯一的问题是'隐式对象MyClass'不能被定义为顶级实体,这是令人讨厌的,因为我现在需要将对象嵌套在另一个类中,并且有一个额外的导入(除非我也嵌套了类有点尴尬)。感谢@Alec分享。 – Danny