英文:
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 var
s 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}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论