我认为我的问题是相关的,但与这里的问题不同。
让我们定义我的第一堂课
case class NoteTaker() {
private var note: Seq[String] = Seq("\n")
override def toString: String = this.note.mkString("\n")
def add(newNote: String): Unit = note ++= Seq(newNote)
}
现在我有一个特质
trait SilentLogger {
import scala.util.{ Failure, Success }
val notepad = NoteTaker()
def tryAndLog[X, Y](x: X, f: X => Y): Y = {
notepad.add("Run with this input: " + x.toString)
(try {
println("Before: " + notepad.toString)
val result = f(x)
println("After: " + notepad.toString)
notepad.add("Get result:-------------------------------\n" + result.toString)
println(notepad.toString)
Success(result)
} catch {
case e: Throwable => {
println(
"Exception occurs:" + "\n" +
notepad.toString + "\n" +
e.getMessage + "\n" +
e.getStackTrace.mkString("\n")
)
Failure(e)
}}).get
}
}
我打算使用此特征与要收集一些笔记的任何类混合使用,并且仅在出现异常时才打印出笔记。否则,我可能只是将其保存到某个地方的日志文件中。
我希望记事本一次创建一次,并且可以为每个对象重复使用。实际上,我不介意它们是否共享同一个记事本。因此,我选择在特征中使用“ val”。
作为示例,我然后创建一个类
case class MyClass (myField : String) extends SilentLogger {
def makeAnother : MyClass = tryAndLog("makeAnother",(x: String) => {
notepad.add(x)
val result = this.copy(myField = this.myField + " addNewField " + x)
notepad.add(result.myField)
return result
})
}
最后,我尝试创建两个对象,如下所示:
scala> val firstObject = MyClass("firstObject")
firstObject: MyClass = MyClass(firstObject)
scala> val secondObject = firstObject.makeAnother
Before:
Run with this input: makeAnother
Exception occurs:
Run with this input: makeAnother
makeAnother
firstObject addNewField makeAnother
null
secondObject: MyClass = MyClass(firstObject addNewField makeAnother)
我真的很困惑。显然发生了异常。但是创建了secondObject很好吗?但是,日志记录消息会在标准输出上打印出来,并显示错误“ null”。
我认为我的问题是我的第一个和第二个对象实际上是使用同一记事本还是分开使用?此处如何定义记事本的初始化和范围?我使用“尝试”的方式有什么问题吗?
这是由于匿名函数显式引起的return
:
(x: String) => {
notepad.add(x)
val result = this.copy(myField = this.myField + " addNewField " + x)
notepad.add(result.myField)
return result
}
在Scala中,当return
在匿名函数中显式声明时,它将抛出NonLocalReturnControl,这将跳过以后的代码块执行,因为您已经捕获了Throwable
,所以也将转到您的catch code block
。
因此,也许您可以return
直接删除以解决此问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句