<p>I have the following function, it works flawlessly</p>
<pre><code>func (r *system) Quantity() int32 {
// r.info.Quantity is type int
return int32(r.info.Quantity)
}
</code></pre>
<p>Now I'm trying to cast it to *int32</p>
<pre><code>func (r *system) Quantity() *int32 {
// r.info.Quantity is type int
return int32(&r.info.Quantity)
}
</code></pre>
<p>But i get the following error <code>cannot use &r.info.Quantity (type *int) as type *int32 in return argument</code>, and of course it seems logic...is there a way to achieve this?</p>
<hr/>**评论:**<br/><br/>juicemia: <pre><p>You're gonna have to make the result of the cast a variable, and return the address of that. I'm on mobile so I can't type it out myself. But basically a cast is an operation, but that operation never gets saved anywhere, so you can't take the address of it because you can't take the address of something that isn't stored. You can have a variable store the result of the cast to int32, and then return the address of that variable. </p></pre>kostix: <pre><p>A minot nitpick: there's no type casts in Go, only type <em>conversions,</em> which are explicit.</p>
<p>This might appears as a minor terminological stuff, but in fact type <em>casts</em> are like what <code>reinterpret_cast<T></code>s in C++ are for -- they interpret bits in memory in another way. Conversions are explicit about what happens.</p></pre>juicemia: <pre><p>You're right. I have a bad habit of using the two interchangeably. </p></pre>Rhelza: <pre><p>Right! that's what i just did, you learn something new everday!</p>
<pre><code>func (r *system) Quantity() *int32 {
q := int32(r.info.Quantity)
return &q
}
</code></pre></pre>juicemia: <pre><p>Glad you got it sorted out!</p></pre>Rhelza: <pre><p>thanks for the explanation! i had no damn idea of that!</p></pre>titpetric: <pre><p>p.s. it makes no sense to return pointers to ints in such a case. The pointer will be 64 bits while int32 itself would be 32. You might as well do the <code>&</code> outside of the function call if you need a pointer, specifically...?</p></pre>epiris: <pre><p>Typically you wouldn't return a pointer like this for a basic numeric type without a specific reason. I imagine you are returning a pointer because you want to mutate it, but you are returning the address of the variable "q" of int32 type, not a pointer to the address used by info.Quantity. Also although I doubt it will come up in practice, this does have the potential for integer overflow as well.</p></pre>Rhelza: <pre><p>I'm using <a href="https://github.com/neelance/graphql-go" rel="nofollow">neelance/graphql-go</a> to implement graphql, so according to the graphql spec it only uses int32, and the library requires an *int32 to be returned </p>
<p><a href="https://github.com/klud1/graphql-docker-api/blob/10dec106b3b9828af058198aa0522c9acc12be3b/resolver/system.go#L82" rel="nofollow">https://github.com/klud1/graphql-docker-api/blob/10dec106b3b9828af058198aa0522c9acc12be3b/resolver/system.go#L82</a></p></pre>tashbarg: <pre><p>But ... now you returned a pointer to q and not to r.info.Quantity ... is that intended? You can neither manipulate r.info.Quantity with that pointer nor does it save you any memory. Why did you want a pointer in the first place?</p></pre>Rhelza: <pre><p>I'm using <a href="https://github.com/neelance/graphql-go" rel="nofollow">neelance/graphql-go</a> to implement graphql, so according to the graphql spec it only uses int32, and the library requires an *int32 to be returned </p>
<p><a href="https://github.com/klud1/graphql-docker-api/blob/10dec106b3b9828af058198aa0522c9acc12be3b/resolver/system.go#L82" rel="nofollow">https://github.com/klud1/graphql-docker-api/blob/10dec106b3b9828af058198aa0522c9acc12be3b/resolver/system.go#L82</a></p></pre>reven80: <pre><p>Try return &int32(r.info.Quantity)</p></pre>Rhelza: <pre><p>Now it says <code>cannot take the address of int32(r.info.Quantity)</code></p></pre>Rhelza: <pre><p>i guess i solved it though by doing the following</p>
<pre><code>func (r *system) Quantity() *int32 {
q := int32(r.info.Quantity)
return &q
}
</code></pre></pre>oilerian: <pre><p>If your intention is to be able to update r.info.Quantity externally, this is the wrong approach. That code is just handing out a pointer to a copy of r.info.Quantity. Any modification to that copy will not be reflected inside r.info.</p>
<pre><code>func (r *system) Quantity() *int32 {
// makes a copy on the heap
q := int32(r.info.Quantity)
// returns a point to the copy
return &q
}
ptr1 := r.Quantity()
// attempt to update
(*ptr1) += 1
ptr2 := r.Quantity()
if *ptr1 != *ptr2 {
// this will always print:
fmt.Println("quantity was not updated!")
}
</code></pre>
<p>You would be better writing accessors:</p>
<pre><code>func (r *system) Quantity() int32 {
return int32(r.info.Quantity)
}
func (r *system) SetQuantity(q int32) {
r.info.Quantity = int(q)
}
// use like this:
q := r.Quantity()
r.SetQuantity(q + 1)
</code></pre>
<p>This avoids exposing the internals of r.info, so in future r.info.Quantity could be changed to use an int64 or a float32 or even a struct, but external code can still continue to use Quantity() and SetQuantity() to access it as if it were an int32.</p></pre>: <pre><p>[deleted]</p></pre>Sythe2o0: <pre><p>It could be nice if the compiler interpreted taking the address of an unaddressable variable as assigning it and then taking its address, maybe. It's not extremely verbose, however.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传