4 ms·
You're right, I'm confusing the issue. I re-read pcwalton's comment and I think understand the point they're trying to make. Not sure the last part was correct
by n0w 10y ago
You're right, I'm confusing the issue. I re-read pcwalton's comment and I think understand the point they're trying to make. Not sure the last part was correct though.
> So Go makes a tradeoff with its structural typing: it doesn't require the small amount of boilerplate code to achieve the pattern you describe, but it prevents you from providing new implementations for types you didn't define.
Shouldn't this be "So Go makes a tradeoff with its structural typing: it does require a small amount of boilerplate code to achieve the pattern you describe, but it allows you to provide new implementations for types you define."?
- masklinn 10y agoWell no because "the pattern you describe" in that context was only implementing stuff on types you own/control, which is basically a function declaration in Go, the problem is that doesn't extend to types you don't control, Go only lets you define methods on local types (types from the same package). By comparison the code pcwalton shows has more upfront boilerplate, you need to explicitly `implement $Interface for $Type`, but it works for both local and non-local types. That's what e.g. Rust does, you can implement a trait on a type if either the trait or the type is local (in theory you could also do so if neither is local but IIRC that's not allowed so conflicts don't have to be handled). Which means you can do this: trait Do { fn do(&self, req: &Request) -> Result<Response> } impl Do for hyper::http::Client { fn do(&self, req: &Request) -> Result<Response> { ... } } impl Do for MockClient { fn do(&self, req: &Request) -> Result<Response> { ... } } There's a higher up-front syntactic cost (in that you have to declare the trait and you have to explicitly implement it even on the local MockClient type) but in return you also can implement it on the non-local "actual" http client.