具有类型约束的 Go 泛型:不能在赋值中使用 false(无类型布尔常量)作为 T 值
Go generics with type constraints: cannot use false (untyped bool constant) as T value in assignment
我有如下一段代码:
func createGrid[T int | bool](size int, forFlooded bool) [][]T {
var tempGrid [][]T
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
if forFlooded {
tempGrid[i][j] = false
} else {
tempGrid[i][j] = -1
}
}
}
return tempGrid
}
我在分配 tempGrid[i][j]
:
的行中收到以下错误
cannot use false (untyped bool constant) as T value in assignment
cannot use -1 (untyped int constant) as T value in assignment
我是这样使用它的:
var grid [][]int;
grid = createGrid(n, false);
var flooded [][]bool;
flooded = createGrid(n, true);
在这里,我得到 CannotInferTypeArgs
(cannot infer T
) 错误。
我也试过将该类型约束提取到接口中。
我做错了什么?
更新:
采纳@kraylog 的建议,我用这个解决了它:
func initialiseGrid[T int | bool](size int, fn func(i, j, size int) T) [][]T {
var tempGrid [][]T
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
tempGrid[i][j] = fn(i, j, size)
}
}
return tempGrid
}
// In some function body:
grid := initialiseGrid(n, func(i, j, size int) int {
if i == 0 || i == size+1 || j == 0 || j == size+1 {
return -1
} else {
return int(math.Floor(rand.Float64() * 6))
}
})
flooded := initialiseGrid(n, func(i, j, size int) bool { return false })
泛型是编译器为您提供的为不同类型创建同一函数的多个实例的快捷方式。
让我们尝试手动完成编译器的工作。您将获得这两个函数 - 一个用于 int:
func createGridInt(size int, forFlooded bool) [][]int {
var tempGrid [][]int
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
if forFlooded {
tempGrid[i][j] = false
} else {
tempGrid[i][j] = -1
}
}
}
return tempGrid
}
还有一个用于布尔值:
func createGridBool(size int, forFlooded bool) [][]bool {
var tempGrid [][]bool
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
if forFlooded {
tempGrid[i][j] = false
} else {
tempGrid[i][j] = -1
}
}
}
return tempGrid
}
突然之间,这不再有意义了,因为您不能像在第一个函数中那样将 false
赋值给 int
,而在第二个函数中则相反。
要解决此问题,您需要使用 T
作为您正在处理的类型。这也解决了将布尔标志传递给函数的代码味道:
func createGrid[T int | bool](size int, fillWith T) [][]T {
var tempGrid [][]T
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
tempGrid[i][j] = fillWith
}
}
return tempGrid
}
你可以这样调用:
createGrid(n, false)
createGrid(n, -1)
我有如下一段代码:
func createGrid[T int | bool](size int, forFlooded bool) [][]T {
var tempGrid [][]T
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
if forFlooded {
tempGrid[i][j] = false
} else {
tempGrid[i][j] = -1
}
}
}
return tempGrid
}
我在分配 tempGrid[i][j]
:
cannot use false (untyped bool constant) as T value in assignment
cannot use -1 (untyped int constant) as T value in assignment
我是这样使用它的:
var grid [][]int;
grid = createGrid(n, false);
var flooded [][]bool;
flooded = createGrid(n, true);
在这里,我得到 CannotInferTypeArgs
(cannot infer T
) 错误。
我也试过将该类型约束提取到接口中。 我做错了什么?
更新:
采纳@kraylog 的建议,我用这个解决了它:
func initialiseGrid[T int | bool](size int, fn func(i, j, size int) T) [][]T {
var tempGrid [][]T
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
tempGrid[i][j] = fn(i, j, size)
}
}
return tempGrid
}
// In some function body:
grid := initialiseGrid(n, func(i, j, size int) int {
if i == 0 || i == size+1 || j == 0 || j == size+1 {
return -1
} else {
return int(math.Floor(rand.Float64() * 6))
}
})
flooded := initialiseGrid(n, func(i, j, size int) bool { return false })
泛型是编译器为您提供的为不同类型创建同一函数的多个实例的快捷方式。
让我们尝试手动完成编译器的工作。您将获得这两个函数 - 一个用于 int:
func createGridInt(size int, forFlooded bool) [][]int {
var tempGrid [][]int
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
if forFlooded {
tempGrid[i][j] = false
} else {
tempGrid[i][j] = -1
}
}
}
return tempGrid
}
还有一个用于布尔值:
func createGridBool(size int, forFlooded bool) [][]bool {
var tempGrid [][]bool
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
if forFlooded {
tempGrid[i][j] = false
} else {
tempGrid[i][j] = -1
}
}
}
return tempGrid
}
突然之间,这不再有意义了,因为您不能像在第一个函数中那样将 false
赋值给 int
,而在第二个函数中则相反。
要解决此问题,您需要使用 T
作为您正在处理的类型。这也解决了将布尔标志传递给函数的代码味道:
func createGrid[T int | bool](size int, fillWith T) [][]T {
var tempGrid [][]T
for i := 0; i <= size+1; i++ {
for j := 0; j <= size+1; j++ {
tempGrid[i][j] = fillWith
}
}
return tempGrid
}
你可以这样调用:
createGrid(n, false)
createGrid(n, -1)