2

我有兴趣在 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

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

4

2 回答 2

3

它们不是恒定的。您只是不能分配给函数外部已声明的变量。像这样的东西会起作用:

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

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

于 2012-06-18T04:56:55.043 回答
2

您可以使用 package 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}}
于 2012-06-18T05:15:16.353 回答