英文:
Golang how to create map to pointer to slice using make
问题
我想创建一个动态初始化的位图数据结构。我尝试使用Go语言的映射(maps)来实现:
type Register map[bool]*[]bool
我初始化映射的方式是:
register := make(Register)
register[true] := make(*[]bool, len(arr)) // arr是我想要创建位图的数组
这显然会导致编译错误:
错误:无法创建类型 *[]bool
我还尝试使用指针语法:
register[true] = &(make([]bool, len(arr)))
这给我带来了错误:
无法获取 make([]bool, len(arr)) 的地址
我希望映射的值为 *[]bool
,这样写回映射时就能保持正常和原地操作。
虽然Go语言对于 map[bool]*[]bool
不会报错,所以它是一个有效的类型。
如果它是有效的,那么在我想要的方式中使用它的惯用方法是什么?如果不是,那么有什么替代方法?
英文:
I want to create a dynamically initialized bitmap data structure. I'm trying to use the golang maps for this:
type Register map[bool]*[]bool
The way I'm initializing the map is:
register := make(Register)
register[true] := make(*[]bool, len(arr)) // arr is the array for which i want to create the bitmap
This obviously creates compilation issue with the error:
error: cannot make type *[]bool
I have also tried using the pointer syntax:
register[true] = &(make([]bool, len(arr)))
Which gives me the error:
cannot take the address of make([]bool, len(arr))
The reason I want the map values to be *[]bool
is so that the write back to the map stays sane and in-place.
While go doesn't complain about map[bool]*[]bool
hence its a valid type.
If it is valid the what is the idomatic way to use it in the fashion I want to. If not then what would be the alternate way?
答案1
得分: 2
使用以下代码创建一个指向切片的指针:
register := make(Register)
s := make([]bool, len(arr)) // 创建可寻址的切片值 s
register[true] = &s
你可以使用new
来消除变量声明,但这种方法不会减少代码行数,而且会增加另一个映射索引操作。
register := make(Register)
register[true] = new([]bool)
*register[true] = make([]bool, len(arr))
声明一个函数将赋值移到单行上:
func makeSlice(n int) *[]bool {
s := make([]bool, len(arr))
return &s
}
...
register := Register{true: makeSlice(len(arr))}
由于映射键有两个可能的值,true和false,你可以通过使用结构体而不是映射来简化代码:
type Register struct {
t, f []bool
}
register := Register{t: make([]bool, len(arr))}
register
中的结构体字段是可寻址的,因此你可以使用®ister.t
来获取*[]bool
。
这个主题的一个变种是使用数组:
type Register [2][]bool
register := Register{1: make([]bool, len(arr))}
如果你只修改切片元素而不修改切片值,那么不需要使用指向切片的指针。
type Register map[bool][]bool
register := make(Register)
register[true] = make([]bool, len(arr))
如果你确实修改切片值,map[bool][]bool
可能更高效且更易于使用。应用程序在修改切片值时需要将其重新赋值给映射,但可以消除间接引用。
英文:
Use the following code to create a pointer to a slice:
register := make(Register)
s := make([]bool, len(arr)) // create addressable slice value s.
register[true] = &s
You can use new
to eliminate the variable declaration, but this approach does not reduce the number of lines of code and it adds another map index operation.
register := make(Register)
register[true] = new([]bool)
*register[true] = make([]bool, len(arr))
Declare a function to move the assignment on to a single line:
func makeSlice(n int) *[]bool {
s := make([]bool, len(arr))
return &s
}
...
register := Register{true: makeSlice(len(arr))}
Because the map keys have two possible values, true and false, you might be able to simplify the code by using a struct instead of a map:
type Register struct {
t, f []bool
}
register := Register{t: make([]bool, len(arr))}
The struct fields in register
are addressable, so you can use &register.t
to get the *[]bool
.
A variation on this theme is to use an array:
type Register [2][]bool
register := Register{1: make([]bool, len(arr))}
If you modify the slice elements only and not the slice value, then there's no need to use a pointer to the slice.
type Register map[bool][]bool
register := make(Register)
register[true] := make([]bool, len(arr))
If you do modify the slice value, the map[bool][]bool
may be more efficient and easier to use. The application will need to assign back to the map when the slice value is modified, but you eliminate the indirections.
答案2
得分: 1
另一种选择是使用new
函数:
package main
import "fmt"
func main() {
type Register map[bool]*[]bool
register := make(Register)
register[true] = new([]bool)
// main.Register{true:(*[]bool)(0xc000004078)}
fmt.Printf("%#v\n", register)
}
https://golang.org/pkg/builtin#new
英文:
Another option is using the new
function:
package main
import "fmt"
func main() {
type Register map[bool]*[]bool
register := make(Register)
register[true] = new([]bool)
// main.Register{true:(*[]bool)(0xc000004078)}
fmt.Printf("%#v\n", register)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论