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

Scala中的Case类的不可变配对实例?

发布时间:2020-12-16 09:04:32 所属栏目:安全 来源:网络整理
导读:我正试图塑造一种可以逆转的关系.例如,北方的反面可能是南方.左派的反面可能是正确的.我想用一个案例类来表示我的关系.我发现了一个类似的解决方案,在这里使用了案例对象,但它并不是我想要的,here. 这是我的非功能代码: case class Relationship(name: Stri
我正试图塑造一种可以逆转的关系.例如,北方的反面可能是南方.左派的反面可能是正确的.我想用一个案例类来表示我的关系.我发现了一个类似的解决方案,在这里使用了案例对象,但它并不是我想要的,here.

这是我的非功能代码:

case class Relationship(name: String,opposite:Relationship)

def relationshipFactory(nameA:String,nameB:String): Relationship = {
  lazy val x:Relationship = Relationship(nameA,Relationship(nameB,x))
  x
}

val ns = relationshipFactory("North","South")

ns // North

ns.opposite // South

ns.opposite.opposite // North

ns.opposite.opposite.opposite // South

可以更改此代码,以便:

>它不会崩溃
>我可以成对地按需创建这些东西.

解决方法

如果你真的想构建具有循环依赖关系的不可变对象的图形,你必须声明相反的def,并且(最好)在混合中再抛出一个懒惰的val:

abstract class Relationship(val name: String) {
  def opposite: Relationship
}

object Relationship {

  /** Factory method */
  def apply(nameA: String,nameB: String): Relationship = {
    lazy val x: Relationship = new Relationship(nameA) {
      lazy val opposite = new Relationship(nameB) {
        def opposite = x
      }
    }

    x
  }

  /** Extractor */
  def unapply(r: Relationship): Option[(String,Relationship)] =
    Some((r.name,r.opposite))

}

val ns = Relationship("North","South")

println(ns.name)
println(ns.opposite.name)
println(ns.opposite.opposite.name)
println(ns.opposite.opposite.opposite.name)

如果你在这个循环依赖循环上运行几百万轮,你可以很快说服自己没有任何不好的事情发生:

// just to demonstrate that it doesn't blow up in any way if you
// call it hundred million times:
// Should be "North"
println((1 to 100000000).foldLeft(ns)((r,_) => r.opposite).name)

它确实打印出“北方”.它不适用于案例类,但您可以随时添加自己的提取器,因此这有效:

val Relationship(x,op) = ns
val Relationship(y,original) = op
println(s"Extracted x = $x y = $y")

它为x和y打印“北”和“南”.

但是,更明显的做法是仅保存关系的两个组件,并添加相反的方法来构造相反的对.

case class Rel(a: String,b: String) {
  def opposite: Rel = Rel(b,a)
}

实际上,这已在标准库中实现:

scala> val rel = ("North","South")
rel: (String,String) = (North,South)

scala> rel.swap
res0: (String,String) = (South,North)

(编辑:李大同)

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

    推荐文章
      热点阅读