Hello great go community!
I'm really struggling with something and I was hoping that you all could
provide some help. I am sure that I am missing something obvious, but I
can't get my head around it.
In the Go spec, I see this statement:
"If the type assertion holds, the value of the expression is the value
stored in x and its type is T. "
That makes sense. I also see this:
"If T is an interface type, x.(T) asserts that the dynamic type of x
implements the interface T."
Still good.
In the Go documentation, I looked up the description of the %T verb:
"a Go-syntax representation of the type of the value"
I then write this code:
package main
import (
"fmt"
)
type Hello interface {
Speak()
}
type HelloListen interface {
Hello
Listen()
}
type HelloString string
func (hs HelloString) Speak() {
fmt.Printf("Hello, World.\n");
}
type HelloInt int
func (hi HelloInt) Speak() {
fmt.Printf("Hello, World.\n");
}
func (hi HelloInt) Listen() {
fmt.Printf("I'm listening.\n");
}
func main() {
var hello Hello
var hellolisten HelloListen
hello = HelloInt(1)
hellolisten = hello.(HelloListen)
hello.Speak()
hellolisten.Speak()
hellolisten.Listen();
fmt.Printf("hello: %T\n", hello);
fmt.Printf("hellolisten: %T\n", hellolisten);
}
The type assertions do as I would expect. The compiler allows me to call
Listen() on hellolisten and not on hello, so the types are handled
correctly. If I try to call hello.Listen(), the compiler gives me an error.
Again, this is as expected.
However, the last two lines of printed output do not give me what I expect.
They produce:
hello: main.HelloInt
hellolisten: main.HelloInt
Having read that the %T verb gives me the type of the variable and that a
type assertion of the form used makes the assigned variable a HelloListen,
I would have expected it to print this:
hello: main.Hello
hellolisten: main.HelloListen
I know that there is a difference between interface values and dynamic
types and dynamic values. Is it possible that the documentation about the
%T is misleading? Should it be more specific that it returns the variable's
"dynamic type."
This would seem to agree with the statement in the spec:
(https://golang.org/ref/spec#Variables)
"The *static type* (or just *type*) of a variable is the type given in its
declaration, the type provided in the new call or composite literal, or the
type of an element of a structured variable. Variables of interface type
also have a distinct *dynamic type*, which is the concrete type of the
value assigned to the variable at run time (unless the value is the
predeclared identifier nil, which has no type). The dynamic type may vary
during execution but values stored in interface variables are always
assignable to the static type of the variable."
I am particularly reading the first sentence which suggests than an
unqualified use of the word "type" refers to the static type. Applying that
logic back to the %T documentation reinforces my incorrect expectation that
the final two lines of the output should be
hello: main.Hello
hellolisten: main.HelloListen
I guess this, then, is the crux of my question:
Should the documentation for %T be updated to say that it prints the
variable's dynamic type?
I hope that this question makes sense. Please tell me where I have gone
wrong -- I know there are tons of smart people on this list with a deep,
deep experience with the language and I look forward to learning anything
that you can offer w.r.t this topic.
Thanks again for fostering such an amazing community of developers. It's a
joy to be a part of it!
Will
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.