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 golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to