question: type assertions : need and syntax

agolangf · · 785 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Beginner gopher here. Intrigued by a couple of language design decisions. Trying to get some insight.</p> <ol> <li><p>Why was the type conversion syntax not co-opted for what type assertion does? I mean, the syntax T(v) seems to be substitutable for v.(T) - with similar effects. What is the reason behind choosing to have the v.(T) syntax as a distinct, separate thing?</p></li> <li><p>Any insight into the choice of the &#34;.&#34; in the type assertion syntax? Given that the &#34;.&#34; has some pretty established semantics as member access &#34;operator&#34;.</p></li> <li><p>Any insight into &#34;overloading&#34; switch keyword for normal switch and type switch? With a pretty orthogonal way the switch value works.</p></li> </ol> <hr/>**评论:**<br/><br/>mwholt: <pre><p>Type conversion and type assertion are distinct, separate things, so their syntax is also.</p> <p>Type conversions morph one type directly into another without fail, checked at compile-time. Type conversions are similar to a function call, where you put in a value and get a different one out, so I imagine that&#39;s why it carries the <code>T(v)</code> syntax.</p> <p>Type assertions are <a href="https://golang.org/ref/spec#Type_assertions">only performed on interfaces</a> - in other words, given<code>v.(T)</code>, <code>v</code> must be an interface. They are most often used to obtain the underlying value of an interface type. But, type assertions can fail as they are executed at runtime, which is why it returns two values - the concrete type and a bool (usually called &#34;ok&#34;).</p> <p>In Go, the dot symbol you refer to is not a member access operator, it is a <em><a href="https://golang.org/ref/spec#Selectors">selector</a></em>. There is no concept of &#34;membership&#34; in Go, just fields and methods. My guess is that, in the case of a type assertion, you are sort of selecting the type underlying an interface, it uses the dot notation - the parentheses indicate a type, rather than a field/method, is inside. The syntax is also congruent with type switches.</p> <p>Type switches make sense then, but you are only switching on a type, not a value. You can <a href="https://golang.org/ref/spec#Switch_statements">read more about this in the Go language spec</a>.</p></pre>aagee: <pre><p>Thanks for your response.</p> <blockquote> <p>Type conversion and type assertion are distinct, separate things</p> </blockquote> <p>Sure. I get what they are, and how they are different. My question was why they decided on separate syntax for type assertions. Could they not have used the T(v) syntax and do what they have to do under the hood? I mean, other languages do this - with no loss of intuitiveness. In fact, you could argue that it is more intuitive.</p> <blockquote> <p>the dot symbol you refer to is not a member access operator, it is a selector</p> </blockquote> <p>Looking at the link, seems like in the expression v.f - they refer to f as the selector - not the &#34;dot&#34;.</p> <blockquote> <p>There is no concept of &#34;membership&#34; in Go, just fields and methods.</p> </blockquote> <p>Well, the notion is similar to &#34;membership&#34; as used in other languages - no? But, sure, we can say that Go has no notion of membership. What is the terminology they use for fields / methods that &#34;belong&#34; to a type then?</p></pre>mwholt: <pre><blockquote> <p>My question was why they decided on separate syntax for type assertions. Could they not have used the T(v) syntax and do what they have to do under the hood?</p> </blockquote> <p>Because <a href="http://play.golang.org/p/Fd0yAQUX-T" rel="nofollow">this</a> maybe? If you want a direct answer from the Go authors, try the golang-nuts mailing list.</p> <blockquote> <p>I mean, other languages do this - with no loss of intuitiveness. In fact, you could argue that it is more intuitive.</p> </blockquote> <p>Sure, but other languages are not Go.</p> <blockquote> <p>Looking at the link, seems like in the expression v.f - they refer to f as the selector - not the &#34;dot&#34;.</p> </blockquote> <p>The dot is a dot. It&#39;s required in a selector expression. I don&#39;t know how else to explain it. What would you use instead?</p> <blockquote> <p>What is the terminology they use for fields / methods that &#34;belong&#34; to a type then?</p> </blockquote> <p>That&#39;s what they use. &#34;Fields&#34; and &#34;methods&#34; describe <em>values</em> that belong to a type. (Although, technically, <a href="http://golang.org/ref/spec#Method_declarations" rel="nofollow">methods receive function values</a>.)</p></pre>aagee: <pre><blockquote> <p>Because this maybe?</p> </blockquote> <p>Not sure what that is meant to clarify.</p> <blockquote> <p>Sure, but other languages are not Go.</p> </blockquote> <p>Go is a language. We are discussing its design choices. And a good way to do that is to compare and contrast.</p> <blockquote> <p>The dot is a dot. It&#39;s required in a selector expression.</p> </blockquote> <p>I was just pointing out that you had called &#34;.&#34; a selector. It seems like it is not.</p> <blockquote> <p>methods receive function values</p> </blockquote> <p>Not sure what you mean by that. Methods are functions that have receivers. I am not sure where you are getting &#34;methods receive function values&#34;.</p></pre>Ainar-G: <pre><p>I&#39;m (obviously) not a part of the Go creators, but here are my thoughts:</p> <ol> <li><p>Type conversion cannot fail at runtime, type assertion can.</p></li> <li><p>On the lower level, <a href="http://research.swtch.com/interfaces" rel="nofollow">interfaces are structs</a>, so you can think of them as having two &#34;fields&#34;, <code>(type)</code> and <code>(T)</code>.</p></li> <li><p>See point 2. It&#39;s not as much &#34;overloading&#34; as just a usual switch on <code>(type)</code> &#34;pseudo-field&#34; of an interface.</p></li> </ol> <p>It&#39;d be interesting to hear from the Go creators though.</p></pre>aagee: <pre><blockquote> <p>not as much &#34;overloading&#34;</p> </blockquote> <p>dunno ... the two seem orthogonal to me. Look at how the switch value behaves:</p> <pre><code>switch t { case &#39; &#39;, &#39;?&#39;, &#39;&amp;&#39;, &#39;=&#39;, &#39;#&#39;, &#39;+&#39;, &#39;%&#39;: return true } switch t := t.(type) { case bool: fmt.Printf(&#34;boolean %t\n&#34;, t) case int: fmt.Printf(&#34;integer %d\n&#34;, t) } </code></pre> <p>In the first case the case values match the value t. In the second case they match the type of t. But from the syntax, it looks like both are switching on value to t. Just in in type switch there is a magical unseen entity that holds the type, that the cases match.</p></pre>

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

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