Vil*_*tas 6 scala control-structure
是否可以创建一个包含多个代码块的自定义控件结构before { block1 } then { block2 } finally { block3 }
?问题是关于糖部分 - 我知道通过将三个块传递给一个方法可以很容易地实现功能doInSequence(block1, block2, block3)
.
一个真实的例子.对于我的测试实用程序,我想创建一个这样的结构:
getTime(1000) {
// Stuff I want to repeat 1000 times.
} after { (n, t) =>
println("Average time: " + t / n)
}
Run Code Online (Sandbox Code Playgroud)
编辑:
最后我提出了这个解决方案:
object MyTimer {
def getTime(count: Int)(action : => Unit): MyTimer = {
val start = System.currentTimeMillis()
for(i <- 1 to count) { action }
val time = System.currentTimeMillis() - start
new MyTimer(count, time)
}
}
class MyTimer(val count: Int, val time: Long) {
def after(action: (Int, Long) => Unit) = {
action(count, time)
}
}
// Test
import MyTimer._
var i = 1
getTime(100) {
println(i)
i += 1
Thread.sleep(10)
} after { (n, t) =>
println("Average time: " + t.toDouble / n)
}
Run Code Online (Sandbox Code Playgroud)
输出是:
1
2
3
...
99
100
Average time: 10.23
Run Code Online (Sandbox Code Playgroud)
它主要基于Thomas Lockney的答案,我刚刚添加了伴侣对象import MyTimer._
谢谢你们,伙计们.
Knu*_*daa 13
一般原则.你当然也可以参加f参数.(注意,在这个例子中,方法的名称没有意义.)
scala> class Foo {
| def before(f: => Unit) = { f; this }
| def then(f: => Unit) = { f; this }
| def after(f: => Unit) = { f; this }
| }
defined class Foo
scala> object Foo { def apply() = new Foo }
defined module Foo
scala> Foo() before { println("before...") } then {
| println("then...") } after {
| println("after...") }
before...
then...
after...
res12: Foo = Foo@1f16e6e
Run Code Online (Sandbox Code Playgroud)
如果您希望这些块按特定顺序出现,则对Knut Arne Vedaa的答案的更改将起作用:
class Foo1 {
def before(f: => Unit) = { f; new Foo2 }
}
class Foo2 {
def then(f: => Unit) = { f; new Foo3 }
}
...
Run Code Online (Sandbox Code Playgroud)
对于您给定的示例,关键是让返回类型getTime
具有after
方法。根据上下文,您可以使用包装这两种方法的单个类或特征。这是一个非常简单的示例,说明您可以如何处理它:
class Example() {
def getTime(x: Int)(f : => Unit): Example = {
for(i <- 0 to x) {
// do some stuff
f
// do some more stuff
}
// calculate your average
this
}
def after(f: (Int, Double) => Unit) = {
// do more stuff
}
}
Run Code Online (Sandbox Code Playgroud)