【问题标题】:Scala generics inference / lower bounds in a value declaration值声明中的 Scala 泛型推断/下限
【发布时间】:2014-08-08 10:25:09
【问题描述】:

我对 Scala 还很陌生,并且一直在尝试在 Lift 中开发一个数据网格,让我能够舒适地显示数据(它也很适合我作为一种 Scala/Lift 练习,以便更好地掌握语言)。无论如何,我似乎陷入了泛型推理。

我有一个所有具体网格都扩展的抽象 Grid 类。然后他们通过columns 字段定义他们的列。我想实现默认排序,但无法弄清楚如何使必要的推理正常工作。这是(非常简化的)代码:

//Lift classes
trait Mapper[A <: Mapper[A]]
trait MappedField[FieldType, OwnerType <: Mapper[OwnerType]]
final case class OrderBy[O <: Mapper[O], T](field: MappedField[T, O])

//models
class Items extends Mapper[Items] {
  object name extends MappedField[String, Items]
}
object Items extends Items

//Grid
abstract class Grid {
  case class Column[O <: Mapper[O]](val label: String, val alias: String, val column: MappedField[_, O])

  val columns: List[Column[_]]

  def sort(by: List[String]) = {
    //HERE I get the inferred type arguments do not conform to method apply's type parameter bounds...
    columns.filter(c => by.contains(c.alias)).map(c => OrderBy(c.column))
  }
}

class ItemsGrid extends Grid {
  val columns = List(new Column[Items]("Name", "name", Items.name))

  def sortWorking(by: List[String]) = {
    val col = new Column[Items]("Name", "name", Items.name)
    OrderBy(col.column)
  }
}

... 无法编译。我在Grid 的sort 方法中应用OrderBy 时收到以下错误:推断类型参数[$2,$1] 不符合方法应用的类型参数边界 [O <: main.mapper>.

由于Items 中的sortWorking 中的虚拟排序工作正常,因此问题必须隐藏在abstract Grid 中的List[Column[_]] 中。我无法正确声明类型,既不使用下限也不使用存在量,并且根本无法说服编译器推断Column 具有正确的类型,因此它们的列表也将如此。

任何想法或指出我正确的方向都非常感谢! 塔德亚什

【问题讨论】:

    标签: scala generics inference


    【解决方案1】:

    下一行的问题:

    val columns: List[Column[_]] // in '_'
    

    我建议将类型参数转换为类型变量(使用嵌入式多态性):

    //Grid
    abstract class Grid {
      trait Column {
        type F
        type O <: Mapper[O]   
    
        val label: String
        val alias: String
        val column: MappedField[F, O]
      }
    
      object Column {
        def apply[F1, O1 <: Mapper[O1]]
          (l : String, a : String, c : MappedField[F1, O1]) =
            new Column {
              type F = F1
              type O = O1
    
              val label = l
              val alias = a
              val column = c
            }
      }
    
      val columns: List[Column]
    
      def sort(by: List[String]) = {
        columns.filter(c => by.contains(c.alias)).map(c => OrderBy(c.column))
      }
    }
    

    Grid 实例看起来像:

    class ItemsGrid extends Grid {
      val columns = List(Column("Name", "name", Items.name))
    
      def sortWorking(by: List[String]) = {
        val col = Column("Name", "name", Items.name)
        OrderBy(col.column)
      }
    } 
    

    【讨论】:

    • 非常感谢,效果很好。另外,您还教了我有关嵌入式多态性的知识。干杯,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 2017-09-08
    • 2023-03-08
    • 2015-06-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    相关资源
    最近更新 更多