【问题标题】:Scala abstract path dependent type problemScala抽象路径依赖类型问题
【发布时间】:2011-03-20 20:33:06
【问题描述】:

有谁知道这个编译器错误是怎么回事?如果我不扩展 INode,错误就会消失。

trait AbsTypes
{
    type TKey
    type TValue
}

trait INode extends AbsTypes
{
    def get(key : TKey) : TValue
    def set(key : TKey, v : TValue) : INode
}

class ANode[TKey,TValue](
  val akey : TKey,
  val aval : TValue
) extends INode
{
    // ERROR : type mismatch;  found   : ANode.this.aval.type (with underlying type TValue)  required: ANode.this.TValue
    def get(key : TKey) : TValue = { aval }
    def set(key : TKey, v : TValue) : INode = {
        new ANode(key,v)
    }
}

【问题讨论】:

    标签: scala types abstract path-dependent-type


    【解决方案1】:

    通用参数不会自动覆盖抽象类型,即使它们具有相同的名称。尝试重命名泛型参数(以避免名称冲突),然后在方法体中声明 TKeyTValue 类型。

    class ANode[A,B](
      val akey : A,
      val aval : B
    ) extends INode {
        type TKey=A
        type TValue=B
        def get(key : TKey) : TValue =  aval 
        def set(key : TKey, v : TValue) : INode = new ANode(key,v)
    }
    

    我想如果编译器在您指定泛型类型名称的行上发出错误,而不是等到您开始使用这些类型,那会很好。

    【讨论】:

    【解决方案2】:

    不幸的是,我没有时间测试我将要编写的内容,但我对您的代码的理解是每个 INode 都会获得它自己的 TValue 类型。所以get操作真正返回的INode.this.TValue与另一个节点上的另一个TValue类型不兼容。

    避免这种情况的方法可能是这样写:

    trait Nodes {
      type TKey
      type TValue
    
      trait INode {
       def get(key : TKey) : TValue
      }
    
      class ANode(
        val akey : TKey,
        val aval : TValue
      ) extends INode
    }
    

    【讨论】:

    • 他的代码仍然会有同样的问题,因为akeyaval 属于泛型命名的类型,而不是抽象类型。 (此外,如果你只编译这段代码,你不会注意到任何编译器错误,因为你没有尝试使用冲突的类型。)
    • 哦,是的,这是复制和粘贴错误。我的意图是使用 Nodes trait 中的类型。
    • 我已编辑您的答案以反映该意图,并删除了我的反对意见。
    • 谢谢,这会起作用,但它会在我的节点实例中添加对外部类型的不需要的引用。我正在尝试使节点尽可能小/高效
    猜你喜欢
    • 2011-03-20
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 2012-02-15
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多