Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why a type assertion works in one case, not in another?

Tags:

go

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

like image 248
24hours Avatar asked Dec 19 '22 14:12

24hours


1 Answers

You are dealing with two different Reader:

  • strings.NewReader() returns a strings.Reader, which isn't an interface.
    But since it implements io.Reader, you can pass it to proxy().
  • proxy() takes an io.Reader, which is an interface.

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")

like image 120
VonC Avatar answered Jan 09 '23 14:01

VonC