如何在Go中执行文字* int64? [英] How do I do a literal *int64 in Go?

查看:420
本文介绍了如何在Go中执行文字* int64?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 * int64 字段的结构类型。

  type SomeType struct {
SomeField * int64
}

我的代码,我想声明一个这样的字面意思(比如说,当我知道所说的值应该是0,或者指向一个0,你知道我的意思)

  instance:= SomeType {
SomeField:& 0,
}

...除此之外无效

  ./ main.go:xx:can not使用& 0(type * int)作为类型* int64的字段值

所以我试试这个

  instance:= SomeType {
SomeField:& int64(0),
}

...但这也行不通

  ./ main.go:xx:不能接受int64(0)的地址

我如何做到这一点?我可以想出的唯一解决方案是使用占位符变量

  var placeholder int64 
placeholder = 0

实例:= SomeType {
SomeField:&placeholder,
}

注意:当它是* int而不是时,& 0 语法工作的很好 * int64 编辑:不,它不。抱歉。



编辑:



显然,我的问题含糊不清。我正在寻找 * int64 的方式。这可以在构造函数中使用,或者用来表示字面值,甚至可以作为其他函数的参数。但是,帮助函数或者使用不同的类型并不是我正在寻找的解决方案。 =http://golang.org/ref/spec#Address_operators =nofollow noreferrer>地址运算符)不允许使用数字常量的地址(不是 untyped 也不是类型的常量)。


操作数必须为 addressable >,即变量,指针间接或片段索引操作;或可寻址结构操作数的字段选择器;或可寻址阵列的数组索引操作。作为寻址能力要求的例外, x [在& x ]的表达式中也可能是(可能的括号内)合成文字

有关这不被允许的推理,请参阅相关问题:查找常量的地址。类似的问题(类似地不允许采用它的地址):

您的选项(全部尝试 Go Playground ):

1)使用 new()



您可以简单地使用内建的 new() 函数分配一个新的零值 int64 并获取它的地址:

  instance:= SomeType {
SomeField:new (int64),
}

但是请注意,这只能用于分配和获取一个指向任何类型的零值的指针。



2)带辅助变量



最简单并推荐用于非-zero el ements是使用一个帮助变量的地址可以被采取:
$ b $ pre $ c $ helper = int64(2)
instance2: = SomeType {
SomeField:& helper,
}



3)With帮助函数



如果你需要这么多次,你可以创建一个帮助函数,它分配并返回一个 * int64

  func create(x int64)* int64 {
return& x
}

使用它:

  instance3:= SomeType {
SomeField:create(3),
}



4)使用单线匿名函数



  instance4:= SomeType {
SomeField:func ()* int64 {i:= int64(4);或者作为一个(更短的)替代方案:返回& i}(),
}

  instance4:= SomeType {
SomeField:func(i int64)* int64 {return& i}(4 ),
}



5)使用切片文字,索引和接收地址



如果您希望 * SomeField 不是 0 ,那么你需要一些可寻址的东西。



你仍然可以做到这一点,但这很丑陋:

  instance5:= SomeType {
SomeField:& [] int64 {5} [0],
}
fmt.Println(* instance2.SomeField)//打印5

这里发生的是一个 [] int64 切片是用一个文字创建的,有一个元素( 5 )。它被索引(第0个元素)并且第0个元素的地址被采用。在后台,一个 [1] int64 的数组也将被分配并用作切片的后备数组。所以这里有很多样板文件。
$ b $ h3> 6)使用帮助程序结构体文字

让我们来看看异常到可寻址性要求:


作为寻址能力要求的例外, x [在& x ]的表达式中也可能是一个(可能用括号括起来的)复合文字


这意味着取一个复合文字的地址,例如结构文字是好的。如果我们这样做,我们将分配结构值并获得一个指针。但是,如果是这样,我们就可以使用另一个要求:可寻址结构操作数的字段选择器。因此,如果结构字面值包含一个类型为 int64 的字段,我们也可以获取该字段的地址!



让我们看看这个选项的实际应用。我们将使用这个wrapper结构类型:

$ p $ type intwrapper struct {
x int64
}

现在我们可以这样做:

  instance6:= SomeType {
SomeField:&(& intwrapper {6})。x,
}

请注意,这个

 &(& intwrapper {6}) .x 

表示如下:

 &安培; ((& intwrapper {6})。x)

但我们可以省略外部括号因为地址运算符& 应用于选择器表达式



另外请注意,在后台会发生以下情况(这也是一种有效的语法):

 &(*(& intwrapper {6}))。x 



7)使用助手匿名结构体字面值



原理与案例#6相同,但我们也可以使用匿名结构文字,所以不需要帮助器/包装器结构类型定义:

  instance7:= SomeType {
SomeField:& amp ;(& struct {x int64} {7})。x,
}


I have a struct type with a *int64 field.

type SomeType struct {
    SomeField *int64
}

At some point in my code, I want to declare a literal of this (say, when I know said value should be 0, or pointing to a 0, you know what I mean)

instance := SomeType{
    SomeField: &0,
}

...except this doesn't work

./main.go:xx: cannot use &0 (type *int) as type *int64 in field value

So I try this

instance := SomeType{
    SomeField: &int64(0),
}

...but this also doesn't work

./main.go:xx: cannot take the address of int64(0)

How do I do this? The only solution I can come up with is using a placeholder variable

var placeholder int64
placeholder = 0

instance := SomeType{
    SomeField: &placeholder,
}

Note: the &0 syntax works fine when it's a *int instead of an *int64. Edit: no it does not. Sorry about this.

Edit:

Aparently there was too much ambiguity to my question. I'm looking for a way to literally state a *int64. This could be used inside a constructor, or to state literal struct values, or even as arguments to other functions. But helper functions or using a different type are not solutions I'm looking for.

解决方案

The Go Language Specification (Address operators) does not allow to take the address of a numeric constant (not of an untyped nor of a typed constant).

The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.

For reasoning why this isn't allowed, see related question: Find address of constant in go. A similar question (similarly not allowed to take its address): How can I store reference to the result of an operation in Go?

Your options (try all on the Go Playground):

1) With new()

You can simply use the builtin new() function to allocate a new zero-valued int64 and get its address:

instance := SomeType{
    SomeField: new(int64),
}

But note that this can only be used to allocate and obtain a pointer to the zero value of any type.

2) With helper variable

Simplest and recommended for non-zero elements is to use a helper variable whose address can be taken:

helper := int64(2)
instance2 := SomeType{
    SomeField: &helper,
}

3) With helper function

Or if you need this many times, you can create a helper function which allocates and returns an *int64:

func create(x int64) *int64 {
    return &x
}

And using it:

instance3 := SomeType{
    SomeField: create(3),
}

4) With a one-liner anonymous function

instance4 := SomeType{
    SomeField: func() *int64 { i := int64(4); return &i }(),
}

Or as a (shorter) alternative:

instance4 := SomeType{
    SomeField: func(i int64) *int64 { return &i }(4),
}

5) With slice literal, indexing and taking address

If you would want *SomeField to be other than 0, then you need something addressable.

You can still do that, but that's ugly:

instance5 := SomeType{
    SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField) // Prints 5

What happens here is an []int64 slice is created with a literal, having one element (5). And it is indexed (0th element) and the address of the 0th element is taken. In the background an array of [1]int64 will also be allocated and used as the backing array for the slice. So there is a lot of boilerplate here.

6) With a helper struct literal

Let's examine the exception to the addressability requirements:

As an exception to the addressability requirement, x [in the expression of &x] may also be a (possibly parenthesized) composite literal.

This means that taking the address of a composite literal, e.g. a struct literal is ok. If we do so, we will have the struct value allocated and a pointer obtained to it. But if so, another requirement will become available to us: "field selector of an addressable struct operand". So if the struct literal contains a field of type int64, we can also take the address of that field!

Let's see this option in action. We will use this wrapper struct type:

type intwrapper struct {
    x int64
}

And now we can do:

instance6 := SomeType{
    SomeField: &(&intwrapper{6}).x,
}

Note that this

&(&intwrapper{6}).x

means the following:

& ( (&intwrapper{6}).x )

But we can omit the "outer" parenthesis as the address operator & is applied to the result of the selector expression.

Also note that in the background the following will happen (this is also a valid syntax):

&(*(&intwrapper{6})).x

7) With helper anonymous struct literal

The principle is the same as with case #6, but we can also use an anonymous struct literal, so no helper/wrapper struct type definition needed:

instance7 := SomeType{
    SomeField: &(&struct{ x int64 }{7}).x,
}

这篇关于如何在Go中执行文字* int64?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆