【问题标题】:How to use nested generics in scala如何在scala中使用嵌套泛型
【发布时间】:2013-08-12 22:24:01
【问题描述】:

edit 简化了示例。添加了更多细节。

我想做的是用方法组成一个类。该类有一个 A[B] 形式的类型参数,其中 A 和 B 是抽象类型(泛型参数),它的方法可以处理 A 或 B 类型的对象,或由 A 或 B 组成的其他类型。例如,该类可能有一个方法,将 A[B] 类型的对象作为参数,并返回 B 类型的对象。

这种模式在 C++ 标准模板库中非常常见。

这在 scala 中可行吗?

在下面的示例中,在 ListDoer 中,A 是抽象类型名称 ListT,B 是抽象类型名称 TElement。 稍后,我尝试提供具体类型,ListT[TElement] = MyList[Double]

class ListDoer[ ListT[TElement] ]
{
  // Processes abstract list type.                 
  def doIt( list:ListT[TElement] ) : TElement = { list.get(0) }   // TElement not found

  // Attempt 2:
  type L=ListT[TElement]               // TElement not found
  def doIt2( list:L ) : TElement ={ list.get(0) }   // TElement not found
}

// More concrete list type
class MyList[TElement]
{
   var None: TElement = _                         
   def get(i:Int): TElement = None   // placeholder               
   def put(i:Int, value:TElement): Unit = { }
}

// MyList[Double] is the concrete list type that doIt should take as a parameter
val doer2 = new ListDoer[ MyList[Double] ]   // MyList[Double] takes no parameters, expected one

val list1 = new MyList[Double]
doer2.doIt( list1 )         // Process list1. Should return list1.get(0)   

list.get(0) 是本示例的占位符实现。

ListDoer 类不应要求 任何 外部类型,而不是作为类型参数提供的那些。 (例如,它不应与列表的特定实现或任何特定集合库中指定的接口相关联)。但是,上面的代码将要求 ListT[ElementT] 有一个方法:get(Int):ElementT 并导致 ListDoer 无法实例化,这不满足。

上面的代码在我看来是合理的(来自 C++ 背景),但在两个地方编译失败:

  • scala 在 ListDoer 中的任何地方都看不到名称 TElement。这使得制作接受或返回 TElement 的方法变得困难

  • 无法实例化 ListDoer

scala 允许这种嵌套使用泛型吗?

【问题讨论】:

  • 如果你能说出你面临的问题以及你想从这段代码中得到什么,也许有人可以提供帮助。
  • 这是一个非常模糊的问题,没有太多的目标,因此很难回答。
  • 谢谢 - 已整理好问题。更多细节。

标签: scala


【解决方案1】:
object XXX {

     class MyList[T] {
          var None: T = _
          def get(k: Int): T = None // placeholder               
          def put(k: Int, v: T): Unit = {}
     }

     class ListDoer[T] {

          // this defines the "wrapper" type 
          // which requires only get method to be there
          type W[T] = { def get(k: Int): T } 

          def doIt(list: W[T]): T = { 
               return null.asInstanceOf[T]
          } 
     }

     type L = Double
     val doer1 = new ListDoer[L] // L takes no parameters, expected one 
     val doer2 = new ListDoer[Double] // L takes no parameters, expected one

     val list1 = new MyList[Double]
     val list2 = List[L]()
     doer1.doIt(list1)

}

【讨论】:

  • 在这种情况下,ListDoer 的约束是 doIt 只接受 T 类型的对象。难道不能让它更通用,以便它接受 A[B] 形式的类型吗?
  • 抱歉——刚刚通过最后的评论意识到是错误的。在您的解决方案中,ListDoer 需要一个 List[T]。我想做的是要求 A[B] where A = type { get(Int):B } - 也就是说,A 是具有方法 get(Int):B 的任何类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
  • 2014-06-03
相关资源
最近更新 更多