代码之家  ›  专栏  ›  技术社区  ›  0__

在Scala中,如何使用通配符来处理更高级的类型?

  •  6
  • 0__  · 技术社区  · 14 年前

    假设我有这种特质

    trait Ctx[C, V[_]]
    

    我无法构造任何接受第二个类型参数未指定(通配符)的Ctx的方法签名。例如:

    def test(c: Ctx[_, _]) = ()
    

    不编译( "error: _$2 takes no type parameters, expected: one" ). 我也不能

    def test(c: Ctx[_, _[_]]) = ()
    

    ( "error: _$2 does not take type parameters" ). 我错过了什么?

    3 回复  |  直到 11 年前
        1
  •  5
  •   huynhjl bhericher    14 年前

    我可以定义这个:

    def test[V[X]](c:Ctx[_,V]) {}
    

    它似乎可以用于类型推断:

    scala> trait Ctx[ C, V[ _ ]]
    defined trait Ctx
    
    scala> def test[V[X]](c:Ctx[_,V]) {}
    test: [V[X]](c: Ctx[_, V])Unit
    
    scala> class P extends Ctx[Int, List]
    defined class P
    
    scala> new P
    res0: P = P@1f49969
    
    scala> test(res0)
    

    编辑 :我怀疑替换是不现实的 Ctx 使用抽象类型,但这正是我能够做到的:

    trait Ctx[C] { type V[X] }
    class CtxOption[C] extends Ctx[C] { type V[X] = Option[X] }
    class CtxList[C] extends Ctx[C] { type V[X] = List[X] }
    
    def test(ctx:Ctx[_]) { println(ctx) }
    
    val ctxOptInt = new CtxOption[Int]
    val ctxListStr = new CtxList[String]
    
    test(ctxOptInt)
    test(ctxListStr)
    
    val list = collection.mutable.ListBuffer[Ctx[_]]()
    list += ctxOptInt
    list += ctxListStr
    list
    

    使用抽象类型 省去了为通配符类型构造函数计算类型参数语法的复杂(或不可能)任务。另外,如 列表缓冲区 例如,您可以处理 V 是不同类型的构造函数( 选择权 列表 在我的例子中)。我提供的第一个解决方案不允许您这样做。

    编辑2 :怎么样?

    trait AbstractCtx[C] { type W[X] }
    trait Ctx[C,V[_]] extends AbstractCtx[C] { type W[X] = V[X] }
    def test(ctx:AbstractCtx[_]) { println(ctx) }
    
        2
  •  4
  •   michid    14 年前

    您需要为的第二个参数传递类型构造函数 Ctx . 如果你只是通过 _ . 也不能用通配符(即。 _[_]] 在飞行中。注意在第一个例子中 _$2 在错误消息中,引用作为第二个参数传递给 Ctx公司 作为一个整体。然而在第二个例子中 _2美元 引用中的第一个通配符类型 _[_] . 请参见错误消息中的位置指示器:

    <console>:6: error: _$2 does not take type parameters
           def test( c: Ctx[ _, _[ _ ]]) {}
                                ^
    

    从这里开始以下工作 V 是所期望的正确类型的类型构造函数 Ctx公司 .

    def test[V[_]]( c: Ctx[ _, V]) {}
    
        3
  •  -1
  •   lisak    10 年前

    都解释清楚了 here . 关注底部的“常见陷阱”部分。