Golang how to create map to pointer to slice using make

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

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中的结构体字段是可寻址的,因此你可以使用&register.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)
}

https://golang.org/pkg/builtin#new

huangapple
  • 本文由 发表于 2021年6月16日 23:49:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/68006075.html
匿名

发表评论

匿名网友

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

确定