加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 过滤掉案例类中的字段

发布时间:2020-12-16 19:23:38 所属栏目:安全 来源:网络整理
导读:我正在尝试从可能位于层次结构中的案例类中过滤掉特定字段: import shapeless._object removeField { import labelled._ import ops.record._ trait RemoveField[T] { def removeField(t: T,field:Witness): HList } object RemoveField { implicit def gen
我正在尝试从可能位于层次结构中的案例类中过滤掉特定字段:

import shapeless._
object removeField {

  import labelled._
  import ops.record._

  trait RemoveField[T] {
    def removeField(t: T,field:Witness): HList
  }

  object RemoveField {

    implicit def generic[F,G](implicit gen: LabelledGeneric.Aux[F,G],sg: Lazy[RemoveField[G]]): RemoveField[F] =
      new RemoveField[F] {
        def removeField(f: F,field:Witness) = sg.value.removeField(gen.to(f),field)
      }

    implicit def product: RemoveField[HNil] =
      new RemoveField[HNil] {
        def removeField(p: HNil,field:Witness): HList = HNil
      }

    implicit def product[K <: Symbol,V,T <: HList]
      (implicit
        key: Witness.Aux[K],selector: Selector.Aux[FieldType[K,V] :: T,K,Symbol],sv: Lazy[RemoveField[V]],st: Lazy[RemoveField[T]]
      ): RemoveField[FieldType[K,V] :: T] =
        new RemoveField[FieldType[K,V] :: T] {
          def removeField(p: FieldType[K,field:Witness): HList = {
            if (selector(p) == selector(p)) sv.value.removeField(p.head,field)
            else p.head :: st.value.removeField(p.tail,field)
          }
        }

    implicit def cnil: RemoveField[CNil] =
      new RemoveField[CNil] {
        def removeField(p: CNil,field:Witness) = HNil
      }

    implicit def coproduct[K <: Symbol,T <: Coproduct]
      (implicit
        key: Witness.Aux[K],V] :+: T] =
        new RemoveField[FieldType[K,V] :+: T] {
          def removeField(c: FieldType[K,V] :+: T,field:Witness): HList =
            c match {
              case Inl( head ) => sv.value.removeField(head,field )
              case Inr( tail ) => st.value.removeField(tail,field )
            }
        }
  }

  implicit class RemoveFieldOps[T](x: T)(implicit removeFieldT: RemoveField[T]) {
    def removeField(field:Witness): HList = removeFieldT.removeField(x,field)
  }

  sealed trait Animal
  case class Cat(name: String,fish: Int) extends Animal
  case class Dog(name: String,bones: Int) extends Animal

  val felix:Cat = Cat("Felix",1)
  val tigger = Dog("Tigger",2)
}

所以当我这样做时:

scala> import removeField._
import removeField._

scala> felix
res0: removeField.Cat = Cat(Felix,1)

scala> felix.removeField('name)

它不编译,我认为问题是找不到RemoveField [G],下面是隐式解析的完整痕迹,但我认为这是应该有效的

<console>:15: removeField.this.RemoveField.<product: error> is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]] because:
type mismatch;
 found   : [K <: Symbol,T <: shapeless.HList](implicit key: shapeless.Witness.Aux[K],implicit selector: shapeless.ops.record.Selector.Aux[shapeless.::[shapeless.labelled.FieldType[K,V],T],implicit sv: shapeless.Lazy[removeField.RemoveField[V]],implicit st: shapeless.Lazy[removeField.RemoveField[T]])removeField.RemoveField[shapeless.::[shapeless.labelled.FieldType[K,T]] <and> => removeField.RemoveField[sh...<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],shapeless.HNil]],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
       felix.removeField('name)
       ^

因为据我所知,LabelledGeneric将使用KeyTag [K,V] :: T aka FieldType [K,V]“返回”V类型的东西
其中K<:符号
和T<:HList 似乎这样做,类型是

Generic.Aux[
 String with KeyTag[Symbol with Tagged[String("name"),String]] :: 
Int with KeyTag[Symbol with Tagged[String("fish")],Int] :: 
shapeless.HNil],V
]

那么为什么我的类型类的产品实例不能“挑选”那个呢?
完整的痕迹:

<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[removeField.Cat,V] because:
type parameters weren't correctly instantiated outside of the implicit tree: inferred type arguments [shapeless.::[String,shapeless.::[Int,Nothing] do not conform to method materializeCoproduct's type parameter bounds [V <: shapeless.Coproduct,R <: shapeless.Coproduct]
       felix.removeField('name)
       ^
<console>:15: shapeless.this.LabelledGeneric.materializeCoproduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[removeField.Cat,G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[removeField.Cat,V]
       felix.removeField('name)
       ^
<console>:15: removeField.this.RemoveField.<product: error> is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
       felix.removeField('name)
       ^
<console>:15: shapeless.this.LabelledGeneric.materializeCoproduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],V]
       felix.removeField('name)
       ^
<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
       felix.removeField('name)
       ^
<console>:15: shapeless.this.LabelledGeneric.materializeProduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],V]
       felix.removeField('name)
       ^
<console>:15: removeField.this.RemoveField.generic is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],shapeless.HNil]]] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],G]
       felix.removeField('name)
       ^
<console>:15: shapeless.this.Lazy.mkLazy is not a valid implicit value for shapeless.Lazy[removeField.RemoveField[this.Out]] because:
hasMatchingSymbol reported error: Unable to derive removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],shapeless.HNil]]]
       felix.removeField('name)
       ^
<console>:15: removeField.this.RemoveField.generic is not a valid implicit value for removeField.RemoveField[removeField.Cat] because:
hasMatchingSymbol reported error: could not find Lazy implicit value of type removeField.RemoveField[G]
       felix.removeField('name)
       ^
<console>:15: RemoveFieldOps is not a valid implicit value for removeField.felix.type => ?{def removeField: ?} because:
could not find implicit value for parameter removeFieldT: removeField.RemoveField[removeField.Cat]
       felix.removeField('name)
       ^
<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[removeField.Cat,shapeless.HNil]]]
       felix.removeField('name)
       ^
<console>:15: removeField.this.RemoveField.generic is not a valid implicit value for removeField.RemoveField[removeField.Cat] because:
hasMatchingSymbol reported error: could not find Lazy implicit value of type removeField.RemoveField[G]
       felix.removeField('name)
       ^
<console>:15: removeField.RemoveFieldOps is not a valid implicit value for removeField.felix.type => ?{def removeField: ?} because:
could not find implicit value for parameter removeFieldT: removeField.RemoveField[removeField.Cat]
       felix.removeField('name)
       ^
<console>:15: error: value removeField is not a member of removeField.Cat
       felix.removeField('name)
             ^

解决方法

事实证明这是不可能的,所以我最终写了这个而不是 https://github.com/caente/equals-except

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读