Scala 构造函数的按名称参数
有没有一种方法可以为正在工作的构造函数按名称获取参数?我需要一种方法来提供一个在对象内部按需/惰性/按名称执行的代码块,并且这个代码块必须能够访问类方法,就像代码块是类的一部分一样 以下测试用例失败:Scala 构造函数的按名称参数,scala,constructor,pass-by-name,Scala,Constructor,Pass By Name,有没有一种方法可以为正在工作的构造函数按名称获取参数?我需要一种方法来提供一个在对象内部按需/惰性/按名称执行的代码块,并且这个代码块必须能够访问类方法,就像代码块是类的一部分一样 以下测试用例失败: package test class ByNameCons(code: => Unit) { def exec() = { println("pre-code") code println("post-code") }
package test
class ByNameCons(code: => Unit) {
def exec() = {
println("pre-code")
code
println("post-code")
}
def meth() = println("method")
def exec2(code2: => Unit) = {
println("pre-code")
code2
println("post-code")
}
}
object ByNameCons {
def main(args: Array[String]): Unit = {
val tst = new ByNameCons {
println("foo")
meth() // knows meth() as code is part of ByNameCons
}
tst.exec() // ByName fails (executed right as constructor)
println("--------")
tst.exec2 { // ByName works
println("foo")
//meth() // does not know meth() as code is NOT part of ByNameCons
}
}
}
输出:
foo
method
pre-code
post-code
--------
pre-code
foo
post-code
我认为这样做可能更容易:
object ByNameCons {
def apply(code: => Unit) = new ByNameCons(code)
}
val tst = ByNameCons { // no "new" here -- can't mix traits either
println("foo")
}
我不知道为什么,但在创建类时使用{}或()似乎会改变行为。使用以下类
class Coder(code: => Unit) {
def exec = {
println("before")
code
println("after")}
}
}
scala> val brackets = new Coder {println("testing")}
testing
brackets: Coder = $anon$1@1af7a03
scala> brackets exec
before
after
现在,如果用另一种方式定义
scala> val parens = new Coder(println("testing"))
parens: Coder = Coder@dca3ed
scala> parens exec
before
testing
after
如所愿。似乎在第一种表示法中,编译器将括号解释为要计算为Unit
的块,而不是调用时计算为Unit
的匿名函数
FWIW,使用({…})也可以很好地工作。这是因为当您创建这样的实例时:
val tst = new ByNameCons {
...
}
。。实际上,您正在创建一个匿名类,就像在java中一样。
上述代码与以下代码相同:
val tst = new ByNameCons() { ... }
。。而按名称传递的正确语法为:
val tst = new ByNameCons( { ... } )
构造函数不能像函数一样省略括号 我使用的是Scala 2.8 nightlies,但这两种变体都不是ByNameCons的一部分,也不知道ByNameCons的方法,因此如果ByNameCons{def meth()..}@hotzen为true,那么传递的代码就不可能调用meth()。我不知道你想让它们成为
ByNameCons
的一部分。与Daniel的帖子中的问题相同,代码不是类的一部分,因此无法访问Coder的方法。你能举一个例子说明val tst=new ByNameCons({…})
的大括号中会放置什么吗?
val tst = new ByNameCons( { ... } )