how to cast *int to *int32?

xuanbao · · 1399 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<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&#39;m trying to cast it to *int32</p> <pre><code>func (r *system) Quantity() *int32 { // r.info.Quantity is type int return int32(&amp;r.info.Quantity) } </code></pre> <p>But i get the following error <code>cannot use &amp;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&#39;re gonna have to make the result of the cast a variable, and return the address of that. I&#39;m on mobile so I can&#39;t type it out myself. But basically a cast is an operation, but that operation never gets saved anywhere, so you can&#39;t take the address of it because you can&#39;t take the address of something that isn&#39;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&#39;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&lt;T&gt;</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&#39;re right. I have a bad habit of using the two interchangeably. </p></pre>Rhelza: <pre><p>Right! that&#39;s what i just did, you learn something new everday!</p> <pre><code>func (r *system) Quantity() *int32 { q := int32(r.info.Quantity) return &amp;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>&amp;</code> outside of the function call if you need a pointer, specifically...?</p></pre>epiris: <pre><p>Typically you wouldn&#39;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 &#34;q&#34; 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&#39;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&#39;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 &amp;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 &amp;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 &amp;q } ptr1 := r.Quantity() // attempt to update (*ptr1) += 1 ptr2 := r.Quantity() if *ptr1 != *ptr2 { // this will always print: fmt.Println(&#34;quantity was not updated!&#34;) } </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&#39;s not extremely verbose, however.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1399 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传