为什么在非最终类中使用普通 val

2023-12-07

如果课程不是最后一堂课,可能会延长。

值有两种可能性:它可能被覆盖并且应该是惰性的,它可能不会被覆盖并且应该是最终的。

如果 val 是最终的 - 您可以假设对它的所有计算都将通过类层次结构进行。如果 val 可能被覆盖,你应该声明它是惰性的,以免在扩展后被破坏。您可以将 val 保留为普通,但这不能保证它会以正确的方式扩展。

什么用例意味着使用普通值?


没有惰性值的类初始化失败的示例

abstract class A {
  lazy val x1 : String = throw new Exception()
  val x2 : String = "mom"
  val x3 : String = x1 + ", " + x2
  println("A: " + x3)
}
class B extends A {
  override lazy val x1: String = "hello"
  println("B: " + x3)
}
class C extends B {
  override val x2: String = "dad"
  println("C: " + x3)
}

测试它:

scala> new B
A: hello, mom
B: hello, mom
res8: B = B@7e2bd615

它有效,但进一步的子类化破坏了已有的功能

scala> new C
A: hello, null
B: hello, null
C: hello, null
res5: C = C@52a53948

在 x2 上设置懒惰可以修复这种情况:

abstract class A {
  lazy val x1 : String = throw new Exception()
  lazy val x2 : String = "mom"
  val x3 : String = x1 + ", " + x2
  println("A: " + x3)
}
class B extends A {
  override lazy val x1: String = "hello"
  println("B: " + x3)
}
class C extends B {
  override lazy val x2: String = "dad"
  println("C: " + x3)
}

正确的初始化顺序:

scala> new C
A: hello, dad
B: hello, dad
C: hello, dad
res6: C = C@5e970110

基本上,你把事情搞砸了。

问题不在于覆盖,问题在于您没有注意初始化事物的顺序。有让它发挥作用的方法,也有让它不起作用的方法,而你选择了后者。这有效:

scala> class C extends { override val x2: String = "dad" } with B {
     |   println("C: " + x3)
     | }
defined class C

scala> new C
A: hello, dad
B: hello, dad
C: hello, dad
res0: C = C@356e3aaf
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在非最终类中使用普通 val 的相关文章

随机推荐

  • 在arm-linux中打印堆栈跟踪

    我按照这篇文章打印堆栈跟踪当我的 gcc C 应用程序崩溃时如何生成堆栈跟踪 它在 x86 linux 上运行良好 谁能教我如何让它在arm linux上运行 我使用的是arm linux gcc 4 4 3 root FriendlyAR
  • 使用 Sinatra 更改 HTTP 状态消息

    我正在编写一个简单的 Sinatra 应用程序 并且给定用户发布包含特定数据的请求 我想返回错误 453 自定义错误代码 以及消息 CLIENT ERROR 或类似的内容 问题是 查看 Sinatra 文档并进行一些测试 我找不到设置响应错
  • 如何检测鼠标指针是否击中 HTML 5 画布上已绘制的线条

    我试图弄清楚如何使用 jQuery 检测用户的鼠标是否点击了 HTML 5 画布上的一行 这是生成画布线的代码
  • R 中的空间自相关分析 (Global Moran's I)

    我有一个点列表 我想使用 Moran s I 并通过将感兴趣的区域除以 4 x 4 样方来检查自相关性 现在我在谷歌上找到的每个例子 例如http www ats ucla edu stat r faq morans i htm 使用某种测
  • 噩梦 JS 不工作

    我知道问题的标题看起来很模糊 但仅此而已 我在我的生产服务器上安装了nodejs 其中phantomjs工作正常 然后我通过安装了噩梦npm install nightmare 我可以在node modules中看到它 我尝试了开发人员在g
  • 如何在选择时突出显示菜单项? [复制]

    这个问题在这里已经有答案了 如何在选择时突出显示菜单项 我尝试使用各种属性修改 styles xml 例如colorPressedHighlight colorActivatedHighlight等 有没有办法让菜单项保持焦点 直到选择其他
  • 在脚本仍在执行时显示结果

    现在为了看到结果 我必须等到整个代码执行完毕 它会挂起直到完成并保持加载状态 一旦完成 它就会显示我正在寻找的所有信息 在脚本仍在运行时是否有办法显示此信息 所以说 如果我在代码顶部的某个地方有一个打印 我希望它在调用时显示 而不是在脚本执
  • 更新 imageView swift 4 的高度约束时无法同时满足约束

    我有一个stack view如下图所示 所以我改变了高度image以编程方式使其适合从我的服务器下载的图像 如果没有图像 则高度限制image将设置为零 这是我这样做的代码 let imageUrl URL string imageStri
  • 查找 CSV 文件/Pandas Dataframe 中标题行的行号

    我正在尝试获取 CSV 文件中包含标题的行的索引或行号 问题是 标题行可以根据我们系统的报告输出上下移动 我无法控制更改此设置 code ht pd read csv file csv test ht get loc Code Code b
  • 如何使用实体框架核心更新与普通 SQL 更新查询相同的多条记录列表?

    通常在 SQL 中我们可以写这样的查询UPDATE users SET isAdult 1 WHERE age gt 18 我想对实体框架核心中满足某些条件的所有行进行一些编辑 我写了这段代码 但出现错误 List
  • tomcat 中基于 JSP Web 应用程序表单的身份验证

    我已将我的应用程序配置为使用基于表单的身份验证 并在 server xml 中设置所需的设置 当我尝试访问受保护的页面时 我被正确重定向到登录页面 在登录页面上 我提供了正确的用户名和密码 但它没有让我登录 而是显示登录错误页面 我正在使用
  • password_hash 每次返回不同的值

    我正在制作一个登录系统 我想对密码进行哈希处理以使其更安全 但它每次都会返回不同的哈希值 甚至无法使用password verify 进行验证 这是我的代码 password password hash password4 PASSWORD
  • 让用户上传并运行Javascript有哪些风险

    如果您有一个 HTML5 游戏厅 允许用户上传一个使用 HTML5 和 Javascript 运行游戏的脚本 假设您的输入没有过滤器 除了只允许 JS 和 HTML 那么潜在的安全风险是什么 陷阱 一种不太可能的可能性是 如果游戏很受欢迎
  • 内部服务器错误

    我在远程服务器上的同一文件夹中有一个 HTML 文件和一个 PHP 文件 从 URL 中 我调用 HTML 文件 而 HTML 文件在提交表单时调用 PHP 文件 但进展并不顺利 当我提交表单时 它显示错误 500内部服务器错误 您要查找的
  • 如何使用 MapReduce API 在映射到云存储之前过滤数据存储数据?

    关于代码实验室here 我们如何在 MapReduce 作业中过滤数据存储数据 而不是获取特定实体类型的所有对象 在下面的映射器管道定义中 唯一的一个输入读取器参数是要处理的实体类型 我在 InputReader 类中看不到可以提供帮助的类
  • Selenium Python:如何网络抓取元素文本

    我正在尝试从轮盘赌游戏中抓取数据 在努力的同时 find element by class name roulette round result position text 我得到这个输出
  • 如何拆分 git repo 并应用 Maven 子模块和 Maven 父模块?

    我需要一些关于如何配置多个存储库的建议 以便它们共享 Maven 父级 并且还配置为 Maven 根项目中的子模块 我正在维护开源项目简单的Java邮件由于可选功能变得越来越大 我计划将项目分成子模块 每个子模块都有自己的 GIT 存储库
  • 如何在方面内使用 ajc 构建参数?

    我需要知道方面内 jar 的名称 以便我可以通过 DeclareParents 创建一个字符串字段 我知道我可以将内容传递给 ajc 编译器 但实际上是否可以使用方面传递的参数 最终结果应该是带有附加字段的类 其中包含我的 jar 的名称作
  • Android 2.2 中的 BackupManager 和 BackupAgent

    我已经查看了文档和示例 BackupRestore 应用程序 并编写了自己的测试应用程序来实现android backupAgent 我延长了BackupAgent类 因为我主要关心的是能够从数据库备份数据 我似乎甚至无法让一个简单的概念验
  • 为什么在非最终类中使用普通 val

    如果课程不是最后一堂课 可能会延长 值有两种可能性 它可能被覆盖并且应该是惰性的 它可能不会被覆盖并且应该是最终的 如果 val 是最终的 您可以假设对它的所有计算都将通过类层次结构进行 如果 val 可能被覆盖 你应该声明它是惰性的 以免