如何在结构体字面量中将bool指针设置为true?

65
我有下面这个函数,它接受一个 bool 指针。我想知道是否有任何标记可以让我在结构体字面量中设置 "is" 字段的值为 true;基本上不用定义新的标识符(即 var x:= true; handler {is: &x})。

我有下面这个函数,它接受一个 bool 指针。我想知道是否有任何标记可以让我在结构体字面量中设置 "is" 字段的值为 true;基本上不用定义新的标识符(即 var x:= true; handler {is: &x})。

package main

import "fmt"

func main() {
    fmt.Println("Hello, playground")
    check(handler{is: new(bool) })
}


type handler struct{
    is *bool
}

func check(is handler){}

1
相关:https://dev59.com/310a5IYBdhLWcg3wF1UL - icza
你可以使用 pointer 包,例如: var _ *bool = pointer.Bool(true) - Xor
5
注意:如果你在处理AWS Go SDK,请注意有一个aws.Bool()函数专门用于此。 - leventov
6个回答

73

你可以这样做,但不是最优解:

h := handler{is: &[]bool{true}[0]}
fmt.Println(*h.is) // Prints true
基本上,它创建一个只有一个值为truebool切片,索引其第一个元素并获取其地址。不会创建新变量,但是有很多样板代码(并且支持数组将保留在内存中,直到其第一个元素的地址存在)。
更好的解决方法是编写一个辅助函数:
func newTrue() *bool {
    b := true
    return &b
}

并且使用它:

h := handler{is: newTrue()}
fmt.Println(*h.is) // Prints true
您也可以使用一行代码的匿名函数来完成这个操作:
h := handler{is: func() *bool { b := true; return &b }()}
fmt.Println(*h.is) // Prints true

或者一个变体:

h := handler{is: func(b bool) *bool { return &b }(true)}

查看所有选项,请查看我的其他答案:如何在Go中进行字面int64?


我想我必须使用丑陋的bools切片,因为语法是作为命令参数提供给生成器的,所以我负担不起一个辅助函数。 - The user with no hat
1
@Theuserwithnohat 我不明白为什么你的情况不允许使用函数。能否分享更多细节? - icza
语法(类型字段)应该提供给命令行/生成器。将函数作为cli参数提供不好。 - The user with no hat
创建一个虚假变量不是更好吗?性能影响呢? - MrR
@MrR 是的,那是更好的选择。可能单行帮助程序也会被内联。 - icza

7

最简单的方法是编写一个短函数,将bool转换为*bool

func BoolPointer(b bool) *bool {
    return &b
}

h := handler{is: BoolPointer(true)}

5

没有语法可以定义指向基本类型的指针,除了由new返回的零值。数字类型和字符串也是如此。

你需要预先创建一个值以获取其地址,或者使用零值创建指针,然后在事后分配新的值。


4

我使用了一个类似 @icza 的函数,但更加方便(对我而言)

我在我的 utils 包 中创建了一个 BoolAddr 函数。

package utils

func BoolAddr(b bool) *bool {
    boolVar := b
    return &boolVar
}

对我来说,使用起来更容易。

package main
    
import "example.com/example/utils"
...
type Example struct {
    isActive *bool
}
    
ex := Expample {
    isActive: utils.BoolAddr(true)
}
...

0
如果您正在使用Go版本1.18或更高版本,您可以利用新引入的泛型功能来创建一个实用函数,该函数可以生成任何给定类型的指针。
func Pointer[T any](d T) *T {
    return &d
}

如何使用:
type Example struct {
    isActive *bool
}

ex := Example {
    isActive: Pointer(true),
}

-2

指针在Go或任何语言中有用的原因之一是它们帮助我们“通过引用”传递参数。因此,如果我们通过引用传递任何东西,我们可以“更改”该物体。一个函数接受一个布尔指针,即使在函数返回后也可以有效地更改布尔值。这正是我们不想要常量的原因,即它们的值不应更改。因此,这种限制是有意义的。

除了上面提到的技巧外,我想在这里补充一点。通常我们使用指向布尔值的指针而不是直接使用布尔值,以有效地使用指针的nil值,否则必须为true或false。如果确实是这种情况,那么您可能希望在函数中直接使用可选的布尔标志,而不是使用布尔指针甚至包装单个布尔指针的结构体,从而省去了完整的结构体要求。当然,如果结构体出于其他原因是必需的,您仍然可以使用上述任何技巧。

顺便说一下,您也可以直接复制布尔值并使用其地址,如下所示。

const check = true
chk := check
fmt.Println(&chk) // will give you the address of chk
chk = false
fmt.Println(chk) // will print false
fmt.Println(check) // will print true

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接