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.

Reply via email to