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

scala – 为什么选项不可扩展?

发布时间:2020-12-16 09:18:39 所属栏目:安全 来源:网络整理
导读:选项不可行是否有理性? 在Scala 2.9,Seq(Set(1,3,2),Seq(4),Option(5))中,flatten没有编译,只是为了实现对我理性的可移动的特征接缝.如果不是这样,那么我看不到不允许的东西.它是什么? PS:在尝试理解的时候,我实现了很多可以编译的东西,比如: scala Seq(
选项不可行是否有理性?

在Scala 2.9,Seq(Set(1,3,2),Seq(4),Option(5))中,flatten没有编译,只是为了实现对我理性的可移动的特征接缝.如果不是这样,那么我看不到不允许的东西.它是什么?

PS:在尝试理解的时候,我实现了很多可以编译的东西,比如:

scala> Seq(Set(1,Map("one"->1,2->"two")).flatten
res1: Seq[Any] = List(1,2,4,(one,1),(2,two))

PS2:我知道我可以写:Seq(Set(1,Option(5).toSeq).flatten或其他丑陋的事情.

PS3:在上个月有接缝工作,使选项看起来更像Traversable,而不实现它:commit,another commit

解决方法

flatMap可能会返回一个Option而不是一个Traversable.虽然早于整个2.8 CanBuildFrom机械.

这个问题在邮件列表上曾经是asked,但没有引起回应.

这是一个例证:

sealed trait OptionX[+A] extends Traversable[A] {
  def foreach[U](f: (A) => U): Unit = if (!isEmpty) f(get)
  def get: A
  def isDefined: Boolean
  def getOrElse[B >: A](default: => B): B
}

case class SomeX[+A](a: A) extends OptionX[A] {
  override def isEmpty = false
  def get = a
  def isDefined = true
  def getOrElse[B >: A](default: => B) = a
}

case object NoneX extends OptionX[Nothing] {
  override def isEmpty = true
  def get = sys.error("none")
  def isDefined = false
  def getOrElse[B](default: => B) = default
}

object O extends App {
  val s: OptionX[Int] = SomeX(1)
  val n: OptionX[Int] = NoneX
  s.foreach(i => println("some " + i))
  n.foreach(i => println("should not print " + i))
  println(s.map(_ + "!"))
}

最后一行返回一个List(“1!”)而不是Option.可能有人可以想出一个可以产生一个SomeX(“1!”)的CanBuildFrom.我的尝试没有成功:

object OptionX {
  implicit def canBuildFrom[Elem] = new CanBuildFrom[Traversable[_],Elem,OptionX[Elem]] {
    def builder() = new Builder[Elem,OptionX[Elem]] {
      var current: OptionX[Elem] = NoneX
      def +=(elem: Elem): this.type = {
        if (current.isDefined) sys.error("already defined")
        else current = SomeX(elem)
        this
      }
      def clear() { current = NoneX }
      def result(): OptionX[Elem] = current
    }
    def apply() = builder()
    def apply(from: Traversable[_]) = builder()
  }
}

我需要明确地传递隐式:

scala> import o._
import o._

scala> val s: OptionX[Int] = SomeX(1)
s: o.OptionX[Int] = SomeX(1)

scala> s.map(_+1)(OptionX.canBuildFrom[Int])
res1: o.OptionX[Int] = SomeX(2)

scala> s.map(_+1)
res2: Traversable[Int] = List(2)

编辑:

所以我可以解决这个问题,并通过OptionX扩展TraversableLike [A,OptionX [A]]并覆盖newBuilder来返回一个OptionX(1).

但是,在SomeX(1)SomeX(2)或for(i< - SomeX(1); j< - List(1,2))yield(i j)中,我得到运行时错误.所以我不认为有可能扩展可扩展性,并且在返回最特定的类型方面做一些理智的事情. 除了可行性,编码风格明智,我不知道在任何情况下,Option都像Traversable一样是件好事.选项表示不总是定义的值,而可扩展定义可以在其中具有多个元素的集合的方法,如drop(n),splitAt(n),take(n),.虽然如果选项也是可移动的,它会提供方便,我认为这可能意味着不太清楚. 在必要时使用toSeq似乎是一种无痛的方式,表明我希望我的选项像Traversable一样.对于某些循环使用的情况,有一个option2Intable隐式转换 – 所以例如这已经有效(它们都返回List(1,2)): >列表(选项(1),选项(2),无).flattenfor(i< - List(0,1); j< - Some(1))yield(i j)(1)(2)

(编辑:李大同)

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

    推荐文章
      热点阅读