Scala,将本地定义的函数传递到列表中?
我不明白下面的代码片段为什么Scala,将本地定义的函数传递到列表中?,scala,programming-languages,Scala,Programming Languages,我不明白下面的代码片段为什么afterDelay(0){…},本地定义的函数可以存储到议程中?有人能帮我理解run函数中的afterDelay(0){…}吗 abstract class Simulation { type Action = () => Unit case class WorkItem(time: Int, action: Action) private var curtime = 0 def currentTime: Int = curtime
afterDelay(0){…}
,本地定义的函数可以存储到议程中?有人能帮我理解run
函数中的afterDelay(0){…}
吗
abstract class Simulation {
type Action = () => Unit
case class WorkItem(time: Int, action: Action)
private var curtime = 0
def currentTime: Int = curtime
private var agenda: List[WorkItem] = List()
private def insert(ag: List[WorkItem], item: WorkItem): List[WorkItem] = {
if (ag.isEmpty || item.time < ag.head.time) item :: ag
else ag.head :: insert(ag.tail, item)
}
def afterDelay(delay: Int)(block: => Unit) {
val item = WorkItem(currentTime + delay, () => block)
agenda = insert(agenda, item)
}
private def next() {
(agenda: @unchecked) match {
case item :: rest =>
agenda = rest
curtime = item.time
item.action()
}
}
def run() {
afterDelay(0) {
println("*** simulation started, time = "+
currentTime +" ***")
}
while (!agenda.isEmpty) next()
}
}
抽象类模拟{
类型Action=()=>Unit
案例类工作项(时间:Int,动作:动作)
私有变量curtime=0
定义当前时间:Int=curtime
私有变量议程:List[WorkItem]=List()
专用def插入(ag:List[WorkItem],item:WorkItem):List[WorkItem]={
如果(ag.isEmpty | | item.time单位){
val项=工作项(当前时间+延迟,()=>块)
议程=插入(议程,项目)
}
私有def next(){
(议程:@未选中)匹配{
案例项::rest=>
议程=休息
curtime=item.time
项目.行动()
}
}
def运行(){
后延迟(0){
println(“***模拟已开始,时间=”+
当前时间+“***”)
}
而(!agenda.isEmpty)next()
}
}
相当于以下内容:
afterDelay(0)({
println(...)
})
调用函数afterDelay
,并将新的工作项
(项
)添加到列表中,而不是函数本身。参数块:=>Unit
是一个“按名称参数”(参见第4.6.1节):用作参数的表达式隐式转换为“无参数方法”(无需首先求值),每当访问方法内的变量时将调用该方法(无需()
)
在这种情况下,即当调用由()=>块产生的函数时:它在项中被调用。action()
在新的工作项添加到列表后的某个点发生(并且afterDelay
返回)
如果它写为(接受函数参数,而不是按名称/thunk):
然后需要通过传入函数调用它:
或者,另一种语法仍然是()=>单元的函数,但可以避免使用外括号:
afterDelay(0) { () => // need a function
println(...)
}
按名称参数从SLS 4.6.1中提取:
值参数的类型可以通过=>
预先确定,例如x:=>T
。这样一个参数的类型就是无参数方法类型=>T
。这表明相应的参数不会在函数应用时求值,而是在函数中的每次使用时求值。也就是说,参数是使用名称调用进行计算的
相当于以下内容:
afterDelay(0)({
println(...)
})
调用函数afterDelay
,并将新的工作项
(项
)添加到列表中,而不是函数本身。参数块:=>Unit
是一个“按名称参数”(参见第4.6.1节):用作参数的表达式隐式转换为“无参数方法”(无需首先求值),每当访问方法内的变量时将调用该方法(无需()
)
在这种情况下,即当调用由()=>块产生的函数时:它在项中被调用。action()
在新的工作项添加到列表后的某个点发生(并且afterDelay
返回)
如果它写为(接受函数参数,而不是按名称/thunk):
然后需要通过传入函数调用它:
或者,另一种语法仍然是()=>单元的函数,但可以避免使用外括号:
afterDelay(0) { () => // need a function
println(...)
}
按名称参数从SLS 4.6.1中提取:
值参数的类型可以通过=>
预先确定,例如x:=>T
。这样一个参数的类型就是无参数方法类型=>T
。这表明相应的参数不会在函数应用时求值,而是在函数中的每次使用时求值。也就是说,参数是使用名称调用进行计算的
您将afterDelay定义为一个。这意味着它有两个参数列表。在scala中,可以用{…}
替换围绕参数列表的括号(…)
。在第二个参数列表中,您使用的是。每次在函数中使用这些参数时,都会对其进行求值。一个很好的例子是。
“按名称调用”参数通常用于定义您自己的控制结构
def do(until: Int)(body: => Unit) {
body
if (until > 1) do(until - 1)(body)
}
do(0)(println("test"))
do(5)(println("test2"))
这是do-until的一个示例。它将打印一次test
,并打印五次test2
您将afterDelay定义为。这意味着它有两个参数列表。在scala中,可以用{…}
替换围绕参数列表的括号(…)
。在第二个参数列表中,您使用的是。每次在函数中使用这些参数时,都会对其进行求值。一个很好的例子是。
“按名称调用”参数通常用于定义您自己的控制结构
def do(until: Int)(body: => Unit) {
body
if (until > 1) do(until - 1)(body)
}
do(0)(println("test"))
do(5)(println("test2"))
这是do-until的一个示例。它将打印一次test
和五次test2
“这里是调用函数结果()=>块的时候。这里发生在afterDelay函数返回后的某个点(在item.action()上)。”--您是说在item.action()期间调用afterDelay吗?我觉得println(“***模拟已启动,time=“+currentTime+”***”)即afterDelay的()=>Unit参数在item期间被调用。action()否,afterDelay
在被调用时被调用。它创建一个新的函数对象(成为WorkItem.action
),它关闭块
参数(将其绑定在一个闭包中)。然后创建新的工作项
,并对其进行排队;调用新函数时(通过item.action()
其他地方