扩展应用程序的对象的属性在 REPL 中访问时具有空值



我的问题是如何在sbt控制台(Scala REPL)中访问DownloadFiles.fileURLList属性?

我创建了一个SBT Scala项目,并将这段代码放在src/main/scala/DownloadFiles.scala

import sys.process._
import biz.neumann.url.NiceURLCodecs._
import java.net._
import java.io._
object DownloadFiles extends App {
val fileURLList = Array(
"https://www.example.com/file1.txt",
"https://www.example.com/file2.txt",
"https://www.example.com/file3.txt"
)
fileURLList.foreach(url => {
val fileName = "downloaded-files/" + new File(new URI(url).getPath).getName;
println(url.decode.encode + ": " + fileName)
new URL(url.decode.encode) #> new File(fileName) !!
})
}

我使用sbt console打开了 Scala REPL,当我访问 DownloadFiles 对象的 fileURLList 属性时,我得到空值(未评估),如下所示。

scala> DownloadFiles.fileURLList

res0:数组[字符串] = 空

相反,我需要的是该对象属性的计算值。

如果有帮助,以下是build.sbt

scalaVersion := "2.12.10"
name := "image-downloader"
organization := "in.bhargav.inc"
version := "1.0"
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2"
libraryDependencies += "biz.neumann" % "nice-url-encode-decode_2.12" % "1.5"

这是Hello扩展App的结果,它间接扩展了DalayedInit从而改变了初始化语义:

@nowarn("""cat=deprecation&origin=scala.DelayedInit""")
trait App extends DelayedInit

快速修复是让fileURLList懒惰

➜ scala
Welcome to Scala 2.13.5 (OpenJDK 64-Bit Server VM, Java 1.8.0_282).
Type in expressions for evaluation. Or try :help.
scala> object DownloadFiles extends App {
|   val fileURLList = Array("https://www.example.com/file1.txt")
| }
object DownloadFiles
scala> DownloadFiles.fileURLList
val res1: Array[String] = null
scala> object DownloadFiles extends App {
|   lazy val fileURLList = Array("https://www.example.com/file1.txt")
| }
object DownloadFiles
scala> DownloadFiles.fileURLList
val res2: Array[String] = Array(https://www.example.com/file1.txt)

这种行为在 Scala 3 中发生了变化,它删除了DelayedInit语义

➜ scala3-repl 
scala> object DownloadFiles extends App {
|   val fileURLList = Array("https://www.example.com/file1.txt")
| }
// defined object DownloadFiles
scala> DownloadFiles.fileURLList                                                                                                            
val res0: Array[String] = Array(https://www.example.com/file1.txt)

App以前的功能,依靠"魔力" 延迟初始化特征,不再可用。应用仍然存在于有限 形式,但它不支持命令行参数,并且将 将来弃。如果程序需要在 Scala 2 和 Scala 3,建议使用显式 main 方法 改用 Array[String] 参数。

代码的第一部分使用一个名为 fileURLList 的变量。 代码的第二部分和 SBT 命令使用 imageURLList。imageURLList 从未声明为变量,因此它是空的。 查找并替换从fileURLList到imageURLList的代码,我敢打赌它会完成您的期望。

不过,我有点惊讶您没有收到其他错误。

最新更新