Pointers 如何在Go中执行文字*int64?
我有一个带有Pointers 如何在Go中执行文字*int64?,pointers,go,struct,literals,Pointers,Go,Struct,Literals,我有一个带有*int64字段的结构类型 type SomeType struct { SomeField *int64 } 在我的代码中的某个时刻,我想声明一个这样的文字(比如,当我知道所说的值应该是0,或者指向一个0时,你知道我的意思) ……但这不起作用 ./main.go:xx: cannot use &0 (type *int) as type *int64 in field value ./main.go:xx: cannot take the address of
*int64
字段的结构类型
type SomeType struct {
SomeField *int64
}
在我的代码中的某个时刻,我想声明一个这样的文字(比如,当我知道所说的值应该是0,或者指向一个0时,你知道我的意思)
……但这不起作用
./main.go:xx: cannot use &0 (type *int) as type *int64 in field value
./main.go:xx: cannot take the address of int64(0)
所以我试试这个
instance := SomeType{
SomeField: &int64(0),
}
……但这也不起作用
./main.go:xx: cannot use &0 (type *int) as type *int64 in field value
./main.go:xx: cannot take the address of int64(0)
我该怎么做?我能想到的唯一解决方案是使用占位符变量
var placeholder int64
placeholder = 0
instance := SomeType{
SomeField: &placeholder,
}
注意:&0
语法在使用*int而不是*int64
时可以正常工作。编辑:没有。很抱歉
编辑:
我的问题显然有太多模棱两可之处。我正在寻找一种方法,可以直接声明一个
*int64
。这可以在构造函数内部使用,也可以用于声明文本结构值,甚至可以用作其他函数的参数。但是助手函数或使用不同类型的函数并不是我要寻找的解决方案。Go语言规范()不允许获取数值常量的地址(既不是非类型常量,也不是类型常量)
操作数必须是可寻址的,即变量、指针间接寻址或切片索引操作;或可寻址结构操作数的字段选择器;或可寻址数组的数组索引操作。作为可寻址性要求的例外,x
[在&x
]的表达式中]也可以是a(可能带括号)
有关不允许这样做的原因,请参阅相关问题:。类似的问题(同样不允许回答):
您的选项(在上尝试所有选项):
1) 使用new()
您只需使用内置函数分配一个新的零值int64
,并获取其地址:
instance := SomeType{
SomeField: new(int64),
}
但请注意,这只能用于分配和获取指向任何类型的零值的指针
2) 带辅助变量
对于非零元素,最简单且推荐的方法是使用一个helper变量,该变量的地址可以是:
helper := int64(2)
instance2 := SomeType{
SomeField: &helper,
}
3) 具有辅助函数
注意:用于获取指向非零值指针的帮助函数可在我的库中的软件包中找到,因此您不必将这些函数添加到所有需要的项目中
或者,如果需要多次,可以创建一个helper函数,该函数分配并返回*int64
:
func create(x int64) *int64 {
return &x
}
使用它:
instance3 := SomeType{
SomeField: create(3),
}
请注意,我们实际上没有分配任何内容,当我们返回函数参数的地址时,Go编译器就这样做了。Go编译器执行转义分析,并在堆(而不是堆栈)上分配局部变量(如果它们可能转义函数)。有关详细信息,请参阅
4) 使用一行匿名函数
或作为(较短的)备选方案:
instance4 := SomeType{
SomeField: func(i int64) *int64 { return &i }(4),
}
5) 使用切片文字、索引和获取地址
如果希望*SomeField
不是0
,则需要可寻址的内容
你仍然可以这样做,但那很难看:
instance5 := SomeType{
SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField) // Prints 5
这里发生的是一个[]int64
切片是用一个文本创建的,它有一个元素(5
)。并对其进行索引(第0个元素),并获取第0个元素的地址。在后台,还将分配一个[1]int64
数组,并将其用作切片的后备数组。所以这里有很多样板
6) 使用helper结构文本
让我们检查一下可寻址性要求的例外情况:
作为可寻址性要求的例外,x
[在&x
]的表达式中]也可以是a(可能带括号)
这意味着获取复合文本的地址(例如结构文本)是可以的。如果我们这样做,我们将分配struct值并获得指向它的指针。但如果是这样的话,我们还需要另一个条件:“可寻址结构操作数的字段选择器”。因此,如果struct literal包含类型为int64
的字段,我们还可以获取该字段的地址
让我们看看这个选项在起作用。我们将使用此包装结构类型:
type intwrapper struct {
x int64
}
现在我们可以做:
instance6 := SomeType{
SomeField: &(&intwrapper{6}).x,
}
请注意
&(&intwrapper{6}).x
指以下各项:
& ( (&intwrapper{6}).x )
但是我们可以省略“外”括号,因为地址运算符&
应用于
还要注意,在后台会发生以下情况(这也是一种有效的语法):
7) 使用helper匿名结构文本
原理与案例#6相同,但我们也可以使用匿名结构文字,因此不需要帮助器/包装器结构类型定义:
instance7 := SomeType{
SomeField: &(&struct{ x int64 }{7}).x,
}
使用返回int64变量地址的函数来解决此问题。
在下面的代码中,我们使用函数f
,它接受整数和
返回保存整数地址的指针值。通过使用这种方法,我们可以很容易地解决上述问题
@icza你通常不会希望它们指向同一个对象,我不是说你会。我只是指出不同之处。@Conslo常量是在编译时计算的。一个有效的指针值,一个有效的内存地址只在运行时存在,所以这与常量不同。@icza,我对方法#6中使用的选择器有一个问题。我在操场url中提到了这个问题。(注释只允许几个字符)@rajkamal只是因为规范不允许它。您可以获取复合文字的地址(第一个示例),但不能获取复合文字字段的地址(规范中未列出)。请注意,您可以获取结构类型变量的字段地址,但不能获取复合文字的地址(“可寻址结构操作数的字段选择器”)。如果您真的想偷懒,这里有一个提供帮助函数的包(解决方案#3)对于每个go原语类型:指向int的指针都是不幸的,因为int与指针占用的空间量相同,所以不能节省空间。它只是添加了一个空值,这个值通常比实际值复杂得多。
instance7 := SomeType{
SomeField: &(&struct{ x int64 }{7}).x,
}
type myStr struct {
url *int64
}
func main() {
f := func(s int64) *int64 {
return &s
}
myStr{
url: f(12345),
}
}