4 ms·
An example: http://golang.org/src/pkg/io/io.go?s=11741:11801#L336 http://golang.org/src/pkg/io/io.go?s=11741:11801#L336 Line 336. io.Copy takes a writer and a
by thirsteh 13y ago
An example:
http://golang.org/src/pkg/io/io.go?s=11741:11801#L336 http://golang.org/src/pkg/io/io.go?s=11741:11801#L336
Line 336. io.Copy takes a writer and a reader, but actually asserts whether they implement ReaderFrom/WriterTo, then use their methods, ReadFrom and WriteTo, if they do. (Same thing with the http package checking if the reader implements Closer, and calling Close if it does, though admittedly 'we should be able to call Close' is a much more unsafe assumption than 'if it implements ReadFrom, and it has the right type signature, we can just call that function instead'.)
The reason it doesn't take values implementing the interfaces ReaderFrom and WriterTo is that io.Copy works even if you don't implement those interfaces.
It's an unfortunate and regrettable predicament, but it's not something that comes up a lot. As others have mentioned in this thread, Go certainly isn't a language with referential transparency by any means--the type system provides minimal sanity checking, and the language itself is memory-safe, but it's not trying to be a "high-assurance language."
- MetaCosm 13y agoThis io.Copy behavior seems like an "optimization"... less explicit than I would like but sticks to the idea of an io.Copy. Having a resource you own Closed on you isn't an optimization, it is a behavior change.
- thirsteh 13y agoI agree. I think I edited my comment to specify that it's a much more unsafe assumption just before you posted your comment.
- bsaul 13y agoThat is SO disturbing... They don't even check whether the parameter implements another interface, they do the check directly on the method by callin it... That's so ugly... Reminds me of my surprise when i realized the math module only worked on float types, and that min/max only existed for some numerical types but not others. The thing in itself probably isn't a big deal, but it really questions the ability of the language to model complex relationships often found in business processes.
- thirsteh 13y ago> That is SO disturbing... They don't even check whether the parameter implements another interface, they do the check directly on the method by callin it... That's so ugly... That's incorrect. The code you see at the top: if rt, ok := dst.(ReaderFrom); ok { return rt.ReadFrom(src) } means: "If dst implements ReaderFrom, then call ReadFrom on this value of that type." You can't arbitrarily call methods that may or may not exist. You can check if a value implements an interface by doing "newVal, ok := val.(suspectedInterface)", and checking if ok is true, or by doing "newVal := val.(suspectedInterface)" and living with a runtime panic if it doesn't implement the interface, then call a method in that interface on the new value newVal, which will be of type suspectedInterface. (If val doesn't implement suspectedInterface--i.e. ok is false--then newVal will be the zero value of suspectedInterface.)
- bsaul 13y agoyeap, i read it too fast. Didn't notice the "er" after dst. thanks for clarifying.
- axelf 13y agoDoes Go not provide method overloading? Couldn't they have 3 versions of the copy method?
- dragonwriter 13y ago> Does Go not provide method overloading? Yes, it does not permit method overloading.