【问题标题】:Scala type constraint of companion type伴随类型的Scala类型约束
【发布时间】:2017-01-08 15:57:10
【问题描述】:

我想要一个具有静态可用函数(由 trait 收缩)的类。然后我想要一个类型参数化的方法,它将这种类型作为其类型参数并访问收缩的静态函数。 (是的,我知道静态这个词是 Java 而不是 Scala,但你知道我的意思。)

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

  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]*/);

任何关于正确解决方案或解决此问题的更好方法的想法?

提前致谢!

【问题讨论】:

标签: scala


【解决方案1】:

没有办法做到这一点。您可以采用的一种方法是通过隐式传递方法(这也称为类型类方法)。您需要通过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*/
}

【讨论】:

  • 这个解决方案很棒!唯一的问题是 implicit object MyClass 不能被定义为顶级实体,这很烦人,因为我现在需要将对象嵌套在另一个类中并对其进行额外的导入(除非我也嵌套了有点尴尬的类)。感谢@Alec 的分享。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 2012-08-21
  • 2012-02-28
相关资源
最近更新 更多