Be careful. You are correct but newcomers to Go often get confused here.

Printf unpacks the interface it is passed to find the concrete element
inside. Doing what reflect requires you to do to discover the type of
an interface is unrelated to the problem at hand.

Watch:

% cat x.go
package main

import "fmt"
import "os"

func main() {
f, _ := os.Stat("x.go")
fmt.Printf("%T\n", f)
}
% go run x.go
*os.fileStat
%

No & necessary. Even though Stat returns an interface, fmt.Printf will
tell you the type inside.

The real thing going on here is that the reflect library allows you to
_read_ unexported values, but not _write_ them. If Printf couldn't
print unexported values (nobody else could either), then debugging
would be a lot harder.

-rob

On Mon, Mar 7, 2022 at 4:39 PM Martin Schnabel <m...@mb0.org> wrote:
>
> one important detail i have not found in the other answers is
> that stat is declared to return a fs.FileInfo, but printf takes
> an empty interface argument and therefor unwraps the interface
> value. so if you want to print the actual variable type of interface
> variables you can pass a pointer (same is often used with reflection):
>
> // prints "type of &fileinfo = *fs.FileInfo"
> fmt.Printf("type of &fileinfo = %T\n", &fileinfo)
>
> On 3/6/22 20:46, jlfo...@berkeley.edu wrote:
> > (go version go1.17.7 linux/amd64)
> >
> > Consider the following trivial program:
> > ------
> > package main
> >
> > import (
> >          "fmt"
> >          "os"
> > )
> >
> > func main() {
> >          file := "."
> >          fileinfo, _ := os.Stat(file)
> >          fmt.Printf("type of fileinfo = %T\n", fileinfo)
> > }
> > ------
> >
> > This runs and produces the output
> >
> > type of fileinfo = *os.fileStat
> >
> > Fine, but notice that "fileStat" isn't capitalized. This means this
> > symbol isn't
> > exported outside the "os" package. Yet, somehow the "fileinfo" variable
> > is assigned
> > this type.
> >
> > Indeed, if I try to explicitly use the "os.fileStat" type in the
> > program, the program fails to compile, e.g.
> >
> > ------------
> > package main
> >
> > import (
> >          "fmt"
> >          "os"
> > )
> >
> > func main() {
> >          var fileinfo *os.fileStat
> >
> >          file := "."
> >          fileinfo, _ = os.Stat(file)
> >          fmt.Printf("type of fileinfo = %T\n", fileinfo)
> > }
> > -----
> > results in
> >
> > ./x3.go:9:16: cannot refer to unexported name os.fileStat
> > ./x3.go:12:14: cannot assign fs.FileInfo to fileinfo (type *os.fileStat)
> > in multiple assignment: need type assertion
> > ./x3.go:12:14: cannot use fs.FileInfo value as type *os.fileStat in
> > assignment: need type assertion
> >
> > Notice the first error message.
> >
> > I also don't understand why the other two error message are produced
> > when all I did was to explicitly declare a variable that was previously
> > assigned a value in a short declaration.
> >
> > What am I missing?
> >
> > Cordially,
> > Jon Forrest
> >
> >
> >
> > --
> > 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
> > <mailto:golang-nuts+unsubscr...@googlegroups.com>.
> > To view this discussion on the web visit
> > https://groups.google.com/d/msgid/golang-nuts/aef48e1e-e0c7-44e4-b62b-2fd1f6e5157bn%40googlegroups.com
> > <https://groups.google.com/d/msgid/golang-nuts/aef48e1e-e0c7-44e4-b62b-2fd1f6e5157bn%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> --
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/b9a88472-5c3b-fb0e-1abc-1cacf763edf1%40mb0.org.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOXNBZRQ_FavziHHBB9%3DVoFWfa6aOp%3DhM2ZHc3Ff3h_7_tAt%3Dw%40mail.gmail.com.

Reply via email to