当前位置: 首页 > 知识库问答 >
问题:

创建Anyval选项的又一次尝试

邵弘义
2023-03-14

我试图实现一个不为包装器消耗额外内存的选项。我创建一个类。Null表示无,非Null值表示有。

class Maybe[+T](private val nullable: T) extends AnyVal {
  @inline final def isDefined: Boolean = {
    println("isDefined called")
    val res = nullable != null
    println(s"result = $res")
    res
  }
  @inline final def get: T = if (isDefined) nullable else throw new NoSuchElementException
  @inline final def getOrElse[B >: T](default: => B): B = if (isDefined) this.get else default
  @inline final def map[B](f: T => B) : Maybe[B] = if (isDefined) Maybe.some(f(this.get)) else Maybe.none
  @inline final def flatMap[B](f: T => Maybe[B]): Maybe[B] = if (!isDefined) Maybe.none else f(get)
  def toOption : Option[T] = if (isDefined) Some(get) else None
}

object Maybe {
  def some[T](value:T) : Maybe[T] = new Maybe(value)

  final val none : Maybe[Nothing] = {
    println("start initializing none")
    val v = new Maybe(null)
    println("1")
    val res = v.asInstanceOf[Maybe[Nothing]]
    println("2")
    res
  }
}

object MaybeTest extends App {
  println("try to create Maybe.none")
  val myNone = Maybe.none
  println("Initialized")
  println(myNone.isDefined)
  println("Accessed")
}

2

已初始化

在com.maybetest$.delayedendpoint$com$maybetest$1(Maybe.scala:34)在com.maybetest$delayedinit$body.apply(maybe.scala:30)在scala.function0$class.apply$mcv$sp(function0.scala:34)在scala.runtime.abstractfunction0.apply$mcv$sp(abstractfunction0.12)在scala.app$$anonfunt$main$1.apply(app.scala:76)(list.scala:392)在scala.collection.generic.traversableForwarder$class.foreach(traversableForwarder.scala:35)在scala.app$class.main(app.scala:76)在com.maybetest$.main(maybe.scala:30)在com.maybetest.main(maybe.scala)

如果我删除“扩展anyval”,一切都很好。有人能解释这样的行为吗?

共有1个答案

班泽语
2023-03-14

@Jasper-M的评论解释了为什么你的解决方案不能工作,但这是接近的:

class Maybe[+T] private (private val nullable: Object) extends AnyVal {
  @inline private final def get0 = nullable.asInstanceOf[T]
  @inline final def isDefined: Boolean = nullable != null
  @inline final def get: T = if (isDefined) get0 else throw new NoSuchElementException
  @inline final def getOrElse[B >: T](default: => B): B = if (isDefined) get0 else default
  @inline final def map[B](f: T => B) : Maybe[B] = if (isDefined) Maybe.some(f(get0)) else Maybe.none
  @inline final def flatMap[B](f: T => Maybe[B]): Maybe[B] = if (!isDefined) Maybe.none else f(get0)
  @inline final def toOption: Option[T] = if (isDefined) Some(get0) else None
}

object Maybe {
  def some[A](value: A) : Maybe[A] = {
    val value1 = value.asInstanceOf[Object]
    assert(value1 != null)
    new Maybe[A](value1)
  }

  private val _none = new Maybe[Null](null)
  def none[A]: Maybe[A] = _none.asInstanceOf[Maybe[A]]

  def apply[A](value: A) = new Maybe[A](value.asInstanceOf[Object])
}

但它实际上并不是“一个选项,不会为包装器消耗额外的内存”:它只是用另一个名称调用null。例如。选项[option[A]]按预期工作,但可能[maybe[A]]不工作(编译器不会告诉您!)。

 类似资料:
  • 我想创建一个屏幕,只显示一次后,应用程序启动。之后,它将只显示主屏幕。我实现这一点的方式只是检查首选项,并根据标志设置当前布局。以这种方式实施它有什么后退吗?有更好的办法吗?

  • 您好,我想平稳地更新seekbar,每秒钟更新一次,所以我创建了一个使用计时器的方法,每秒钟更新seekbar,但它每秒钟都在更新歌曲,我到处搜索,但没有找到解决方案,我不想使用任何处理程序,我想用这个方法修复 在这里我实现了歌曲开始时的方法 这是我的全部代码

  • 我试图在Spring Tool Suite上创建一个新的Spring Starter项目,但每次都会出现相同的错误: IoException:将C:\users\eumagnun\appdata\local\temp\downloadcache170748875579761919425966721163343\pw2avw5ccnm2hcpbelrlcrb1zjk=.part重命名为 有人有过这个

  • 我需要创建对的订阅,该订阅在第一次调用时立即被处理掉。 有没有像这样的东西: 我的用例是,我正在一个快速路由处理程序中创建一个订阅,每个请求都会多次调用该订阅。

  • 我正在开发一个应用程序,使用ActionBar导航,我有3个标签(我不使用tabhost)如下图: 在第一个选项卡中,将显示一个名为FragmentListItem的片段,如果单击Item1,FragmentListItem将被另一个名为FragmentItemDetails的片段替换,该片段显示所选项的详细信息。 我的问题是,当我选择Tab2或tab3,然后再次选择Tab1,我得到的不再是fra

  • 我正在尝试使用输入在Web上创建仪表板表格。然而,问题是,数据是从回调中从数据库创建的,因此,我不知道列的名称,除非pandas DataFramework是使用回调函数创建的。我已经检查了我是否得到了正确的数据。但是,我们无法显示它。我使用了多个输出选项(使用破折号0.41) 我的代码看起来如下:(我没有提供函数的详细信息,它生成的熊猫数据帧在回调某些Func,因为这是不重要的这个破折号代码麻烦