可重新配置的函数变量

huangapple go评论85阅读模式
英文:

Reconfigurable function variables

问题

我对在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至少在顶级上是常量。有没有办法绕过这个问题?

英文:

I'm interested in reassigning factory functions for testing reasons within Go, to mitigate the risk of using a factory function within a given package when wanting to mock one of its types.

I've seen people pass factory functions as arguments to a containing function, and creating a struct that holds factories as data members. Is it instead possible to keep a top-level function variable and someway overwrite one implementation with another within a given file? I've tried the below:

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}}
}

But when I build the code, 6g gives me the following error on the closing line of the last assignment:
non-declaration statement outside function body

This makes it seem like vars of function types are const, at least at the top level. Is there any way to get around this?

答案1

得分: 3

它们不是常量。你不能在函数外部给已经声明的变量赋值。像这样的代码可以工作:

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

就 Go 语言而言,函数外部的变量赋值没有特定的顺序。因此,你只能执行一次。

英文:

They are not constant. You just can not assign to an already declared variable outside of a function. Something such as this will work:

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

As far as go is concerned, the variable assignments outside of a function do not happen in any particular order. As a consequence, you can only do it once.

答案2

得分: 2

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

package main

import "fmt"

var x = 1

// 设置变量的模拟值
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}}
}

// 设置变量的模拟值
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}}
英文:

You could use the package init function to set the mock value of package variables. For example,

package main

import "fmt"

var x = 1

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

func init() {
	mock()
}

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

Output:

2

For your example,

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))
}

Output:

{default {0 0}}

huangapple
  • 本文由 发表于 2012年6月18日 11:37:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/11076656.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定