可重配置的函数变量

时间:2012-06-18 03:37:09

标签: go

我有兴趣在Go中重新分配工厂函数以进行测试,以减少在想要模拟其中一种类型时在给定包中使用工厂函数的风险。

我见过人们将工厂函数作为参数传递给包含函数,并创建一个将工厂保存为数据成员的结构。是否可以保留顶级函数变量,并在某个给定文件中覆盖另一个实现?我试过以下内容:

type AirportFactory func (string, int, int) Airport

var makeAirport AirportFactory = func(n string, x int, y int) Airport {
    return airport{name: n, pos: Position{X: x, Y: y}}
}

makeAirport = func(n string, x int, y int) Airport {
    return airport{name:"default", pos:Position{X:0, Y:0}}
}

但是当我构建代码时,6g在最后一个赋值的结束行上给出了以下错误: non-declaration statement outside function body

这使得函数类型的var似乎是const,至少在顶层。有没有办法解决这个问题?

2 个答案:

答案 0 :(得分:3)

他们不是一成不变的。您无法在函数外部分配已声明的变量。像这样的东西会起作用:

func changeAirport() {
    makeAirport = func(n string, x int, y int) Airport {
        return airport{name:"default", pos:Position{X:0, Y:0}}
    }
}

就go而言,函数外部的变量赋值不会以任何特定顺序发生。因此,你只能做一次。

答案 1 :(得分:2)

您可以使用包init函数来设置包变量的模拟值。例如,

package main

import "fmt"

var x = 1

// set mock values of variables
func mock() {
    x = 2
}

func init() {
    mock()
}

func main() {
    fmt.Println(x)
}

输出:

2

对于您的示例,

package main

import "fmt"

type Position struct {
    X int
    Y int
}
type Airport struct {
    name string
    pos  Position
}

type AirportFactory func(string, int, int) Airport

var makeAirport AirportFactory = func(n string, x int, y int) Airport {
    return Airport{name: n, pos: Position{X: x, Y: y}}
}

// set mock values of variables
func mock() {
    makeAirport = func(n string, x int, y int) Airport {
        return Airport{name: "default", pos: Position{X: 0, Y: 0}}
    }
}

func init() {
    mock()
}

func main() {
    fmt.Println(makeAirport("name", 1, 1))
}

输出:

{default {0 0}}