Scala passing type parameters to object

后端 未结 4 1903
北恋
北恋 2021-02-20 09:11

In Scala v 2.7.7

I have a file with

class Something[T] extends Other

object Something extends OtherConstructor[Something]

This throws

4条回答
  •  生来不讨喜
    2021-02-20 09:46

    You can solve the general problem of needing object Foo[T] by moving the type parameter to the methods in object Foo:

    class Foo[T](t1: T, t2: T)
    
    object Foo {
      def apply[T](x: T): Foo[T] = new Foo(x, x)
      def apply[T](x: T, y: T): Foo[T] = new Foo(x, y)
    }
    

    If you really need one object per T, you can make a class, and have the type-free companion return it from apply.

    class Foo[T](t1: T, t2: T)
    
    class FooCompanion[T] {
      def apply(x: T): Foo[T] = new Foo(x, x)
      def apply(x: T, y: T): Foo[T] = new Foo(x, y)
    }
    
    object Foo {
      def apply[T] = new FooCompanion[T]
    }
    
    object demo extends App {
      val x: Foo[Double] = Foo.apply.apply(1.23)  // this is what is really happening
      val y: Foo[Int] = Foo[Int](123)             // with the type both apply calls are automatic
    }
    

    Note this will re-construct the Foo[T] companion on each call so you would want to keep it light and stateless.

    An explicit solution the the problem above:

    class Other
    
    class OtherConstructor[O <: Other] {
      def apply(o: O): O = o  // constructor 1 in base class
    }
    
    class Something[T](value: T) extends Other
    
    class SomethingConstructor[T] extends OtherConstructor[Something[T]] {
      def apply(o: T, s: String) = new Something[T](o)   // constructor 2 in subclass
    }
    
    object Something {
      def apply[T] = new SomethingConstructor[T] // the "constructor constructor" method
    }
    
    object demoX extends App {
      val si = new Something(123)
      val sd = new Something(1.23)
    
      val si1: Something[Int] = Something[Int](si)                    // OtherConstructor.apply
      val sd1: Something[Double] = Something[Double](1.23, "hello")   // SomethingConstructor[Double].apply
    }
    

提交回复
热议问题