英文:
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
(无法推断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
}
// 在某个函数体中:
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 })
英文:
I have the following piece of code:
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
}
I get the following errors on the lines where I'm assigning 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
This is how I'm using it:
var grid [][]int;
grid = createGrid(n, false);
var flooded [][]bool;
flooded = createGrid(n, true);
Here, I get CannotInferTypeArgs
(cannot infer T
) error.
I've also tried extracting that type constraint to an interface.
What am I doing wrong?
Update:
Taking @kraylog's suggestions, I solved it using this:
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 })
答案1
得分: 3
泛型是编译器为你提供的一种快捷方式,用于为不同类型创建多个相同函数的实例。
让我们尝试手动完成编译器的工作。你将得到这两个函数 - 一个用于 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
}
和一个用于 bool 类型:
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)
英文:
Generics are a shortcut the compiler gives you for creating multiple instances of the same function, for different types.
Let's try to do the compiler's work manually. You'll get these two functions - one for 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
}
and one for bool:
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
}
Suddenly, this doesn't make sense anymore, since you can't assign false
to int
as in the first function, and the other way around in the second.
To solve the problem, you need to use T
as the type you're working on. This also solves the code smell of passing a boolean flag to a function:
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
}
And you can call this with:
createGrid(n, false)
createGrid(n, -1)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论