我对多重任务的概念感到困惑。给出以下代码:
func fibonacci() func() int {
current, next := 0, 1
return func() int {
current, next = next, current+next
return current
}
}
如果两个变量同时出现在作业的左侧和右侧,那么如何评估作业?
答案 0 :(得分:2)
订单在语言规范的Order of Evaluation中定义。
在包级别,初始化依赖性确定变量声明中各个初始化表达式的求值顺序。否则,在计算表达式,赋值或返回语句的操作数时,所有函数调用,方法调用和通信操作都按词汇从左到右的顺序进行评估。
其中提供了复杂评估顺序的一个很好的例子
y[f()], ok = g(h(), i()+x[j()], <-c), k()
函数调用和通信以f(),h(),i(),j(),&lt; -c,g()和k()的顺序发生。但是,没有指定与x的评估和索引以及y的评估相比较的那些事件的顺序。
操作数从左到右进行评估。在评估操作数之后赋予next
的事实是无关紧要的。
然后是Assignments:
转让分两个阶段进行。首先,左侧的索引表达式和指针间接操作(包括选择器中的隐式指针间接)的操作数和右侧的表达式都按通常的顺序进行评估。其次,分配按从左到右的顺序进行。
因此,此处的顺序为next
,然后是current+next
。 next
的结果已分配到current
,然后current+next
的结果已分配给next
。
答案 1 :(得分:1)
The Go Programming Language Specification
转让分两个阶段进行。一,索引的操作数 表达式和指针间接(包括隐式指针) 左边的选择器中的间接和)上的表达式 权利都按照通常的顺序进行评估。第二,任务 按从左到右的顺序进行。
说明多项任务的常用示例是交换。例如,
self.window?
游乐场:https://play.golang.org/p/HcD9zq_7tqQ
输出:
package main
import "fmt"
func main() {
{
i, j := 7, 42
fmt.Println(i, j)
// swap i and j - implicit temporaries
i, j = j, i
fmt.Println(i, j)
}
fmt.Println()
{
i, j := 7, 42
fmt.Println(i, j)
// swap i and j - explicit temporaries
ti, tj := i, j
i, j = tj, ti
fmt.Println(i, j)
}
}
使用隐式临时变量的一个语句多重赋值等效于(使用显式临时变量的两个多赋值语句的简写)。
您的斐波那契示例使用显式顺序和临时变量转换为:
7 42
42 7
7 42
42 7
游乐场:https://play.golang.org/p/XFq-0wyNke9
输出:
package main
import "fmt"
func fibonacciMultiple() func() int {
current, next := 0, 1
return func() int {
current, next = next, current+next
return current
}
}
func fibonacciSingle() func() int {
current, next := 0, 1
return func() int {
// current, next = next, current+next
// first phase, evaluation, left-to-right
t1 := next
t2 := current + next
// second phase, assignmemt, left-to-right
current = t1
next = t2
return current
}
}
func main() {
m := fibonacciMultiple()
fmt.Println(m(), m(), m(), m(), m(), m())
s := fibonacciSingle()
fmt.Println(s(), s(), s(), s(), s(), s())
}
答案 2 :(得分:0)
来自spec:
转让分两个阶段进行。首先,左侧的索引表达式和指针间接操作(包括选择器中的隐式指针间接)的操作数和右侧的表达式都按通常的顺序进行评估。其次,分配按从左到右的顺序进行。