Sorry to reply to myself, but I gave this some additional thought and wanted to add a few comments. Please see below!
Thanks again! On Tuesday, June 20, 2017 at 12:52:58 AM UTC-4, Will Hawkins wrote: > > 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? > It seems perhaps that the ambiguity in the fmt package's documentation is not really the place to look for a solution (if this is even a problem). I say that because the reflect package seems to give, what I would consider, unexpected output. When calling the TypeOf() function, I would expect the result to be the "type" of the variable. Since that is an unqualified use of the term, after reading the spec I would expect it to return the static type. If I add the following to the code snippet from above: fmt.Printf("TypeOf(hello).String(): %v\n", reflect.TypeOf(hello).String()); fmt.Printf("TypeOf(hellolisten).String(): %v\n", reflect.TypeOf(hellolisten).String()); I would expect: TypeOf(hello).String(): main.Hello TypeOf(hellolisten).String(): main.HelloListen and instead I get: TypeOf(hello).String(): main.HelloInt TypeOf(hellolisten).String(): main.HelloInt That leads me to wonder if the best place to look at this is in the wording of that first sentence of the spec which seems to define what an unqualified use of the word type means. Again, I really hope that these questions aren't silly. Thank you for taking the time to educate me on where I have gone wrong! Will > 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.