4

Here is the problematic source code:

http://play.golang.org/p/lcN4Osdkgs

package main
import(
    "net/url"
    "io"
    "strings"
) 

func main(){
    v := url.Values{"key": {"Value"}, "id": {"123"}}
    body := strings.NewReader(v.Encode())
    _ = proxy(body)
    // this work 

    //invalid type assertion: body.(io.ReadCloser) (non-interface type *strings.Reader on left)
    _, _ = body.(io.ReadCloser)

}

func proxy( body io.Reader) error{
    _, _ = body.(io.ReadCloser)
    return  nil
}

Can someone tell me why this code wont work ?

The error occur here:

body := strings.NewReader(v.Encode())

rc, ok := body.(io.ReadCloser)

// invalid type assertion: body.(io.ReadCloser) (non-interface type *strings.Reader on left)

However proxy(body io.Reader) do the same thing but have no error. Why?

http://play.golang.org/p/CWd-zMlrAZ

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
24hours
  • 191
  • 2
  • 14

1 Answers1

11

You are dealing with two different Reader:

For non-interface types, the dynamic type is always the static type.
A type assertion works for interfaces only, which can have arbitrary underlying type.
(see my answer on interface, and "Go: Named type assertions and conversions")

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks!! , your comment really help me understand a lot about interface (from 0 to enough ) . I modified my code so it will work [http://play.golang.org/p/C4tA2Xaq4p](http://play.golang.org/p/C4tA2Xaq4p). I have to convert strings.Reader to interface before doing any type assertion. – 24hours Jun 04 '14 at 08:02