string Conversion to io.Reader

21,829 views
Skip to first unread message

Robert

unread,
Sep 14, 2010, 1:36:00 AM9/14/10
to golang-nuts
I have a variable of type string that I have escaped and formatted and
want to pass to http.Post(uri, bodytype, body) as the body argument
which is of type io.Reader.

1. How do you determine which types implement io.Reader short of
scanning all the source code.

2. Apart from reading byte by byte, what is the best way to convert
type string to something that implements io.Reader.

Andrew Gerrand

unread,
Sep 14, 2010, 1:46:45 AM9/14/10
to Robert, golang-nuts
On 14 September 2010 15:36, Robert <hancock...@gmail.com> wrote:
> I have a variable of type string that I have escaped and formatted and
> want to pass to  http.Post(uri, bodytype, body) as the body argument
> which is of type io.Reader.
>
> 1.  How do you determine which types implement io.Reader short of
> scanning all the source code.

http://golang.org/search?q=Read

It would be cool to have a code search that searches for types with a
specific method set. It would be challenging to implement, what with
type embedding etc. Worth looking into, though.

> 2.  Apart from reading byte by byte, what is the best way to convert
> type string to something that implements io.Reader.

Use bytes.Buffer, which implements Reader:

b := bytes.NewBufferString("your string")

Andrew

Rob 'Commander' Pike

unread,
Sep 14, 2010, 1:54:48 AM9/14/10
to Andrew Gerrand, Robert, golang-nuts
strings.Reader may be even better for you.

-rob

yy

unread,
Sep 14, 2010, 2:46:09 AM9/14/10
to Andrew Gerrand, Robert, golang-nuts
2010/9/14 Andrew Gerrand <a...@golang.org>:

> It would be cool to have a code search that searches for types with a
> specific method set.

It would be cool, indeed.

However, although I love the duck-typing of interfaces as much as
anybody else, I have noticed that many times you implement interfaces
on purpose. It would be nice if that was reflected in the
documentation *and* it was checked by the compiler at compile time.

I propose to use an Implements function to do this. For example, if I
want MyType to implement the io.ReaderWriter interface I would write:

func (mt MyType)Implements() io.ReaderWriter {
return io.ReaderWriter(mt)
}

That function would be a convention, but no language changes are
needed. This way, the compiler would tell me if MyType does not
implement ReaderWriter and it would appear clearly in the
documentation.

Of course, this does not solve the problem of knowing all the types
which implement an interface, but if this convention was followed
writing the tool that Andrew is suggesting would not be such a
challenging task.

--
- yiyus || JGL . 4l77.com

Andrew Gerrand

unread,
Sep 14, 2010, 3:06:53 AM9/14/10
to yy, Robert, golang-nuts
On 14 September 2010 16:46, yy <yiyu...@gmail.com> wrote:
> However, although I love the duck-typing of interfaces as much as
> anybody else, I have noticed that many times you implement interfaces
> on purpose. It would be nice if that was reflected in the
> documentation *and* it was checked by the compiler at compile time.
>
> I propose to use an Implements function to do this...

Why do that, when you can already do this:

type A interface { Foo() }
]type T struct {}
func (t T) Foo() {}
var _ = A(T{}) // fail to compile if T doesn't satisfy A

> Of course, this does not solve the problem of knowing all the types
> which implement an interface, but if this convention was followed
> writing the tool that Andrew is suggesting would not be such a
> challenging task.

It's not worth adding complexity to the language just to make it
marginally easier to write tools like this.

Andrew

chris dollin

unread,
Sep 14, 2010, 3:18:46 AM9/14/10
to Andrew Gerrand, yy, Robert, golang-nuts

Um, yy's suggestion doesn't add anything to the language. It adds
a convention for use.

One can argue about which of the alternative conventions are
more obvious / compact / greppable / whatever, but those are
different arguments.

Chris

--
Chris "allusive" Dollin

yy

unread,
Sep 14, 2010, 3:21:26 AM9/14/10
to Andrew Gerrand, Robert, golang-nuts
2010/9/14 Andrew Gerrand <a...@golang.org>:

> Why do that, when you can already do this:
>
> type A interface { Foo() }
> ]type T struct {}
> func (t T) Foo() {}
> var _ = A(T{}) // fail to compile if T doesn't satisfy A

Because this won't appear in the package documentation. I want to say
to the people using my package: "I am implementing this interface".
While I think not having to do this is a good thing, I don't know
what's the problem with doing it.

> It's not worth adding complexity to the language just to make it
> marginally easier to write tools like this.

This would not add any complexity to the language (it would just be a
convention that would require no language change) and the intention is
not to "make marginally easier" to write any tool, but to explicitly
say to the compiler and the users that a type is implementing an
interface. I will accept the argument that go does not want to make
this explicit, although I don't fully understand why.

jimmy frasche

unread,
Sep 14, 2010, 3:24:15 AM9/14/10
to yy, Andrew Gerrand, Robert, golang-nuts
On Tue, Sep 14, 2010 at 12:21 AM, yy <yiyu...@gmail.com> wrote:
> Because this won't appear in the package documentation. I want to say
> to the people using my package: "I am implementing this interface".

You could also add documentation that said "I am implementing this interface".

Andrew Gerrand

unread,
Sep 14, 2010, 3:26:53 AM9/14/10
to chris dollin, yy, Robert, golang-nuts
On 14 September 2010 17:18, chris dollin <ehog....@googlemail.com> wrote:
> Um, yy's suggestion doesn't add anything to the language. It adds
> a convention for use.
>
> One can argue about which of the alternative conventions are
> more obvious / compact / greppable / whatever, but those are
> different arguments.

You're right; in my haste I didn't read closely enough. Apologies yy.

Regardless, I'm not impressed by the suggested convention (which has
been discussed before). I understand its merits, but IMO it just adds
noise. I'd rather just have a good tool for matching interface
signatures.

Andrew

fango

unread,
Sep 14, 2010, 4:09:18 AM9/14/10
to golang-nuts
6nm -g *.a under pkg/darwin_amd64 lists all symbols including func
name and type but unfortunately on different lines.

I spent some time (and stopped) trying to figure out how to link them
together so a simple `grep -n 'Read([]uint8) (int, os.Error)'` to get
all that implement such func. Is there such tool already?

Cheers,
Fango
Message has been deleted

Robert

unread,
Sep 14, 2010, 11:33:58 AM9/14/10
to golang-nuts
Andrew, thanks b := bytes.NewBufferString("your string") worked, and
I
understand why. It would have taken me a while to find this.

Rob, I tried strings.Reader but it doesn't implement io.Reader as
required by http.Post.
cannot use body (type strings.Reader) as type io.Reader in function
argument:
strings.Reader does not implement io.Reader (Read method requires
pointer receiver)

Russ Cox

unread,
Sep 14, 2010, 1:17:32 PM9/14/10
to Robert, golang-nuts
> Rob,  I tried strings.Reader but it doesn't implement io.Reader as
> required by http.Post.
> cannot use body (type strings.Reader) as type io.Reader in function
> argument:
>        strings.Reader does not implement io.Reader (Read method requires
> pointer receiver)

If you run

godoc strings Reader

or visit http://golang.org/pkg/strings/#Reader

you'll find that the Read method is on *Reader
so either you need to construct and pass a *Reader
on your own, or you can call the constructor
function NewReader also listed in that documentation.

Russ

Robert Hancock

unread,
Sep 14, 2010, 1:21:58 PM9/14/10
to r...@golang.org, golang-nuts
Russ, you are correct.  I still keep forgetting to use godoc.  My omission.

I'll try strings.Reader since it seems to be the more intuitive of the two statements.  Thanks.
--
Bob Hancock

bobhancock.blogspot.com
Twitter - bob_hancock and nycgtug
Buzz - nycgtug.box


Nigel Tao

unread,
Sep 14, 2010, 9:39:53 PM9/14/10
to yy, golang-nuts
On 14 September 2010 16:46, yy <yiyu...@gmail.com> wrote:
> I propose to use an Implements function to do this. For example, if I
> want MyType to implement the io.ReaderWriter interface I would write:
>
> func (mt MyType)Implements() io.ReaderWriter {
>    return io.ReaderWriter(mt)
> }

This won't work if you want to declare that MyType implements more
than one interface, since methods can't be overloaded.

Steven

unread,
Sep 14, 2010, 10:26:48 PM9/14/10
to Nigel Tao, yy, golang-nuts
func (mt MyType) Implements() (io.ReadWriter, fmt.Stringer, hash.Hash) {
    return io.ReadWriter(mt), fmt.Stringer(mt), hash.Hash(mt)
}

Not that I'm advocating this form, just pointing out that it does work for multiple interfaces. However, an advantage is that it actually documents, whereas `var _ = io.ReadWriter(new(MyType))` doesn't (I don't think... haven't checked, but it shouldn't).

Rob 'Commander' Pike

unread,
Sep 14, 2010, 10:45:38 PM9/14/10
to Steven, Nigel Tao, yy, golang-nuts
You're working too hard. You don't need the conversions in the return
statement, since MyType is assignable to those interfaces. This
works:

type A interface { a() }
type B interface { b() }
type C interface { c() }

type X int

func (X) a() {}
func (X) b() {}
func (X) c() {}

func (x X) Implements() (A, B, C) {
return x, x, x
}

-rob

Steven

unread,
Sep 14, 2010, 10:47:40 PM9/14/10
to Rob 'Commander' Pike, Nigel Tao, yy, golang-nuts
Right, that's what I get for extending an example without thinking: duplicated redundancy :) 
Reply all
Reply to author
Forward
0 new messages