<p><a href="https://go-talks.appspot.com/github.com/guregu/slides/comiket/comiket.slide#21" rel="nofollow">https://go-talks.appspot.com/github.com/guregu/slides/comiket/comiket.slide#21</a></p>
<p>Hey all. I'm new to go and I came across the website linked above when I was searching for general Golang game development tricks.</p>
<p>The code in question is on slide 21 (should come up if you hit the link.)</p>
<pre><code>type Alignment int // 属性
const (
Neutral Alignment = iota // 壁など
Good // プレイヤー
Evil // モンスター
)
type Aligned interface {
Alignment() Alignment
}
func AlignmentOf(o Object) Alignment {
if a, ok := o.(Aligned); ok {
return a.Alignment()
}
return Neutral
}
</code></pre>
<p>I think understand everything that is going on here except for one method call.</p>
<p>what does o.(Aligned) do in the AlignmentOf(o Object) function? Is this a typo? Is this some idiom I've never seen? I tried running this code in the Go tour test bench but I couldn't quite figure out the spirit of o.(Aligned).</p>
<p>Has anyone seen this before or is this just a typo?</p>
<hr/>**评论:**<br/><br/>natefinch: <pre><p>That's a type conversion. If the concrete value behind the value <code>o</code> fulfills the interface Aligned, then <code>a</code> will be an interface that wraps the value in <code>o</code>, and <code>ok</code> will be true. And if the value in <code>o</code> does not fulfill the interface, <code>a</code> will be nil and <code>ok</code> will be false.</p>
<p>It's a runtime way to convert from one interface to another. </p></pre>tv64738: <pre><p>It's a type assertion not a conversion. <a href="https://golang.org/ref/spec#Type_assertions" rel="nofollow">https://golang.org/ref/spec#Type_assertions</a></p></pre>natefinch: <pre><p>Sorry, yes, assertion.</p></pre>clockworkgoblin: <pre><p>Thanks!</p>
<p>I had another question.</p>
<p>We assume in the above example that whatever we're sending into the AlignmentOf() function implements the Object interface.</p>
<p>Let's say: </p>
<pre><code>type Object interface {
ID() ID
}
</code></pre>
<p>and let's say we have a class:</p>
<pre><code>type Goblin struct {
id ID
alignment Alignment
}
</code></pre>
<p>What happens if we do this?:</p>
<pre><code>func (g *Goblin) ID() ID {
return g.id
}
</code></pre>
<p>Even though a Goblin (not a *Goblin) object can call the ID() method (as in Goblin.ID()) the compiler tells me that a Goblin does not implement the Object interface.</p>
<pre><code>Goblin does not implement Object (ID method has pointer receiver)
</code></pre>
<p>It appears that we can play fast and loose with pointer receivers except when it comes to implementing interfaces?</p></pre>natefinch: <pre><p>yep. Pointer auto-dereferencing is a feature that only works for dereferencing. In the Go compiler's mind, *Goblin is a completely different type than Goblin (which makes sense if you think about it - one is a pointer and one is a struct).</p>
<p>Here's more detail: <a href="https://npf.io/2014/05/intro-to-go-interfaces/" rel="nofollow">https://npf.io/2014/05/intro-to-go-interfaces/</a></p></pre>jerf: <pre><p>Here's an <a href="https://play.golang.org/p/QLuZRpBJVv" rel="nofollow">example on the playground that runs so you can see</a>.</p>
<p>Interfaces expose a view onto certain objects that is a subset of the underlying object's methods, but it does not erase the type of that object, so you can still either directly extract it or match it against another interface via the type conversion. Another common case you'll see in practice is having an <code>io.Reader</code> or <code>io.Writer</code> and needing to check if it's also an <code>io.Closer</code>, to create a function that works with any <code>io.Reader</code> but works <em>correctly</em> with <code>io.Closer</code>s as well.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传