golang多重任务评估

时间:2018-02-16 23:07:45

标签: go

我对多重任务的概念感到困惑。给出以下代码:

func fibonacci() func() int {
    current, next := 0, 1
    return func() int {
        current, next = next, current+next
        return current
    }
}

如果两个变量同时出现在作业的左侧和右侧,那么如何评估作业?

3 个答案:

答案 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+nextnext的结果已分配到current,然后current+next的结果已分配给next

答案 1 :(得分:1)

  

The Go Programming Language Specification

     

Assignments

     

转让分两个阶段进行。一,索引的操作数   表达式和指针间接(包括隐式指针)   左边的选择器中的间接和)上的表达式   权利都按照通常的顺序进行评估。第二,任务   按从左到右的顺序进行。

说明多项任务的常用示例是交换。例如,

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

  

转让分两个阶段进行。首先,左侧的索引表达式和指针间接操作(包括选择器中的隐式指针间接)的操作数和右侧的表达式都按通常的顺序进行评估。其次,分配按从左到右的顺序进行。