scala – 隐式参数不适用于unapply.如何隐藏提取器中无处不在的
显然,提取器对象中的unapply / unapplySeq不支持隐式参数.假设这里有一个有趣的参数a,以及一个令人不安的无处不在的参数b,当提取c时,它会很好地隐藏起来.
[编辑]:在我的intellij / scala-plugin安装中看起来有些东西被破坏了.我无法解释.我最近和intellij有很多奇怪的问题.重新安装后,我再也不能重新解决我的问题了.确认unapply / unapplySeq允许隐式参数!谢谢你的帮助. 这不起作用(**编辑:是的,确实如此):** trait A; trait C; trait B { def getC(a: A): C } def unapply(a:A)(implicit b:B):Option[C] = Option(b.getC(a)) 在我对理想提取器应该是什么样的理解中,其中的意图也直观地清楚地表明了Java人员,这种限制基本上禁止依赖于附加参数的提取器对象. 你通常如何处理这个限制? 到目前为止,我已经有了这四种可能的解决方案: 1)我想要改进的最简单的解决方案:不要隐藏b,提供参数b和a,作为元组形式的unapply的正常参数: object A1{ def unapply(a:(A,B)):Option[C] = Option(a._2.getC(a._1)) } 在客户端代码中: val c1 = (a,b) match { case A1(c) => c1 } 我不喜欢它,因为有更多的噪音偏离,解构为c在这里很重要.此外,由于必须确信实际使用此scala代码的java人员面临一个额外的合成新颖性(元组括号).他们可能会得到反斯卡拉的侵略“这一切是什么?……为什么不首先使用正常的方法并检查是否?”. 2)在类中定义提取器,封装对特定B的依赖,导入该实例的提取器.在导入站点对于java人来说有点不寻常,但是在模式匹配站点b被很好地隐藏,并且直观地看出会发生什么.我的最爱.我错过了一些缺点? class BDependent(b:B){ object A2{ def unapply(a:A):Option[C] = Option(b.getC(a)) } } 客户端代码中的用法: val bDeps = new BDependent(someB) import bDeps.A2 val a:A = ... val c2 = a match { case A2(c) => c } } 3)在客户端代码范围内声明提取器对象. b是隐藏的,因为它可以在本地范围内使用“b”.阻碍代码重用,严重污染客户端代码(此外,必须在代码使用之前说明). 4)具有未应用的返回选项功能B => C.这允许导入和使用依赖于ubitious-parameter的提取器,而不直接向提取器提供b,而是在使用时提供结果. Java人员可能会对函数值的使用感到困惑,b不会隐藏: object A4{ def unapply[A,C](a:A):Option[B => C] = Option((_:B).getC(a)) } 然后在客户端代码中: val b:B = ... val soonAC: B => C = a match { case A4(x) => x } val d = soonAC(b).getD ... 进一步评论: >正如this answer中所建议的那样,“视图边界”可能有助于使提取器与隐式转换一起工作,但这对隐式参数没有帮助.出于某种原因,我不想使用隐式转换来解决问题. 解决方法
你的第一行代码在什么意义上不起作用?对于提取器方法,隐式参数列表当然没有任意禁止.
考虑以下设置(我使用普通的旧类而不是案例类来表明这里没有额外的魔法发生): class A(val i: Int) class C(val x: String) class B(pre: String) { def getC(a: A) = new C(pre + a.i.toString) } 现在我们定义一个隐式B值,并使用unapply方法创建一个提取器对象: implicit val b = new B("prefix: ") object D { def unapply(a: A)(implicit b: B): Option[C] = Option(b getC a) } 我们可以这样使用: scala> val D(c) = new A(42) c: C = C@52394fb3 scala> c.x res0: String = prefix: 42 正如我们所期望的那样.我不明白为什么你需要一个解决方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |