代码之家  ›  专栏  ›  技术社区  ›  Greg

如何使类型依赖于隐式参数的方法参数?

  •  3
  • Greg  · 技术社区  · 6 年前
    trait JsonOps[J] {
      type ObjectFields
      def partitionObjectFields(fields: ObjectFields, fieldNames: List[String]): (ObjectFields, ObjectFields)
    }
    
    def compilerNoLikey[J](stuff: ops.ObjectFields)(implicit ops:JsonOps[J]) = {}
    
    def compilerLikey[J](stuff: Any)(implicit ops:JsonOps[J]) = {
        val stuff2 = stuff.asInstanceOf[ops.ObjectFields]
    }
    

    问题是,ObjectFields是在ops中定义的,它发生在签名中的stuff之后。

    我该如何解读?

    第二个def有效,但我不喜欢传递任何东西。我希望编译器能够检查传入的内容。

    1 回复  |  直到 6 年前
        1
  •  4
  •   Dmytro Mitin    6 年前

    您应该为其多引入一个类型参数 compilerLikey 写下 JsonOps

    trait JsonOps[J] {
      type ObjectFields
      def partitionObjectFields(fields: ObjectFields, fieldNames: List[String]): (ObjectFields, ObjectFields)
    }
    
    def compilerLikey[J, OF](stuff: OF)(implicit ops: JsonOps[J] { type ObjectFields = OF }) = {}
    

    或使用 Aux-pattern

    trait JsonOps[J] {
      type ObjectFields
      def partitionObjectFields(fields: ObjectFields, fieldNames: List[String]): (ObjectFields, ObjectFields)
    }
    
    object JsonOps {
      type Aux[J, OF] = JsonOps[J] { type ObjectFields = OF }
    }
    
    def compilerLikey[J, OF](stuff: OF)(implicit ops: JsonOps.Aux[J, OF]) = {}