On Sun, Feb 28, 2021 at 4:03 AM Deiter <hwaterf...@gmail.com> wrote: > My (clearly flawed) interpretation of interface types suggested that I > could assign the first result from c.StdoutPipe() to anything that > implements io.ReadCloser. >
To try and explain the flaw in the argument: These two statements are different (they are duals of each other) • You can assign anything to an `io.ReadCloser`, which has a `Read` and a `Close` method • You can assign an `io.ReadCloser` to anything, which has a `Read` and a `Close` method Only the first one is true. You are assuming the second. An interface is box, containing a value whose concrete type is not known at compile time, but only at runtime - but it is guaranteed that the concrete type has certain methods. A type-assertion unpacks that box at runtime and checks if it contains a specific concrete type. The type-assertion paniced, because it turns out that the box did not contain a `*PipeReader`. That shouldn't be terribly surprising in and off itself. If I give you a (physical) box and tell you "I don't know what is in here, but it definitely is yellow", you might think it contains a banana and unwrap it, only to find it actually contained a lemon - but I didn't lie, I told you the contents are yellow, but that doesn't mean you can assume it's a specific yellow thing. It contains "something that's yellow", not "anything that's yellow" :) Returning an interface allows a function to not make promises about the specific, concrete type it returns. Doing that can have multiple reasons, among others: 1. They want the flexibility to return something else in the future, when the implementation changes 2. What they return might change, depending on circumstance. For example, net.Dial <https://golang.org/pkg/net/#Dial> returns a different concrete type depending on the address family used. 3. They might need to return an interface to satisfy a different interface themselves. For example, any function implementing `io.Reader` must return the `error` interface, not a concrete error type. Either way, unless its docs tell you to, you probably shouldn't assume anything of the content of the box you are getting, except what's on the label. Ideally, you shouldn't unpack it - and if you do, be prepared for being surprised by the contents :) > The io.PipeReader documentation <https://golang.org/pkg/io/#PipeReader> > indicates that it provides both a Read() and a Close() function with the > appropriate signatures, so I figured I’d try connecting up both ends of a > pipe: > > rPipe, _ := io.Pipe() > p, err := cmd.StdoutPipe() > if err != nil { > log.Fatal(err) > } > rPipe = p > > The first clue that I was misguided was when the compiler indicated that I > needed a type assertion. I put one in to see what would happen: > rPipe = p.(*io.PipeReader) > > Everything compiled, but not surprising, it panics: > panic: interface conversion: io.ReadCloser is *os.File, not *io.PipeReader > > I suppose it makes sense that an assignment operator requires more than > simply interface compatibility. A couple of questions: > > 1. How is one supposed to know what type is required in a situation > like this? Is a type assertion panic the only way to discover that a > *os.File type is required?! > 2. Any suggestions on how I can get a io.PipeReader to connect with > the cmd.StdoutPipe()? > > -- > 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/d7c51270-5e2c-439d-a1bb-d78fd65a6a25n%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/d7c51270-5e2c-439d-a1bb-d78fd65a6a25n%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/CAEkBMfGFdjcn4tU59wKyMCf0Yx%3D14PSKTWKW4GEYf4aBTpni6g%40mail.gmail.com.