Duck typing: How to implicitly convert from an interface to another interface in go
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I'm new to go and I wish to make two packages with (very) loosely coupled API between a uses and a provider. For this, I wish to use go's ability to implicitly implement interfaces and implicit conversion.
Both the provider and the user have their own defined interfaces (for exemple provider returns a provider.A and user accepts a user.A).
With this pattern, I can convert from one type to the other instead of importing the interfaces from another package.
This works fine with simple interfaces, but as soon as a method takes an interfaces as an input, the conversion from one type to the other become impossible.
Why doesn't go allow this kind of conversion? Is there any workaround?
working example:
package main
// Provider
type A interface{
AddString(string)
}
type a struct{
b string
}
func (a *a) AddString(b string) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddString(string)
}
func Main() {
var _ A2 = NewA()
}
example that cause problems:
package main
// Provider
type A interface{
AddB(B)
}
type B interface{}
type a struct{
b B
}
func (a *a) AddB(b B) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddB(B2)
}
type B2 interface{}
func Main() {
var _ A2 = NewA() // error..
}
go interface type-conversion
add a comment |
I'm new to go and I wish to make two packages with (very) loosely coupled API between a uses and a provider. For this, I wish to use go's ability to implicitly implement interfaces and implicit conversion.
Both the provider and the user have their own defined interfaces (for exemple provider returns a provider.A and user accepts a user.A).
With this pattern, I can convert from one type to the other instead of importing the interfaces from another package.
This works fine with simple interfaces, but as soon as a method takes an interfaces as an input, the conversion from one type to the other become impossible.
Why doesn't go allow this kind of conversion? Is there any workaround?
working example:
package main
// Provider
type A interface{
AddString(string)
}
type a struct{
b string
}
func (a *a) AddString(b string) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddString(string)
}
func Main() {
var _ A2 = NewA()
}
example that cause problems:
package main
// Provider
type A interface{
AddB(B)
}
type B interface{}
type a struct{
b B
}
func (a *a) AddB(b B) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddB(B2)
}
type B2 interface{}
func Main() {
var _ A2 = NewA() // error..
}
go interface type-conversion
That's probably not how interfaces are used in Go. I have t oadmit I have no idea what you are trying to do.
– Volker
Nov 22 '18 at 6:11
Ok, first this is not for a serious project, this is just me toying around. My goal here is to see if I can create an API with absolutely zero coupling what so ever using some kind of duck-typing. The user doesn't know anything about the provider and the provider doesn't know anything about the user, they are hosted on separated gits, and can't import from one another. The wiring is done by dependency-injection. The user tells what it needs (interface A2) and the provider what it provide (interface A). And I was hoping that A could be converted to A2 since the interfaces are the same.
– Matthieu
Nov 22 '18 at 10:01
add a comment |
I'm new to go and I wish to make two packages with (very) loosely coupled API between a uses and a provider. For this, I wish to use go's ability to implicitly implement interfaces and implicit conversion.
Both the provider and the user have their own defined interfaces (for exemple provider returns a provider.A and user accepts a user.A).
With this pattern, I can convert from one type to the other instead of importing the interfaces from another package.
This works fine with simple interfaces, but as soon as a method takes an interfaces as an input, the conversion from one type to the other become impossible.
Why doesn't go allow this kind of conversion? Is there any workaround?
working example:
package main
// Provider
type A interface{
AddString(string)
}
type a struct{
b string
}
func (a *a) AddString(b string) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddString(string)
}
func Main() {
var _ A2 = NewA()
}
example that cause problems:
package main
// Provider
type A interface{
AddB(B)
}
type B interface{}
type a struct{
b B
}
func (a *a) AddB(b B) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddB(B2)
}
type B2 interface{}
func Main() {
var _ A2 = NewA() // error..
}
go interface type-conversion
I'm new to go and I wish to make two packages with (very) loosely coupled API between a uses and a provider. For this, I wish to use go's ability to implicitly implement interfaces and implicit conversion.
Both the provider and the user have their own defined interfaces (for exemple provider returns a provider.A and user accepts a user.A).
With this pattern, I can convert from one type to the other instead of importing the interfaces from another package.
This works fine with simple interfaces, but as soon as a method takes an interfaces as an input, the conversion from one type to the other become impossible.
Why doesn't go allow this kind of conversion? Is there any workaround?
working example:
package main
// Provider
type A interface{
AddString(string)
}
type a struct{
b string
}
func (a *a) AddString(b string) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddString(string)
}
func Main() {
var _ A2 = NewA()
}
example that cause problems:
package main
// Provider
type A interface{
AddB(B)
}
type B interface{}
type a struct{
b B
}
func (a *a) AddB(b B) {
a.b = b
}
func NewA() A {
return &a{nil}
}
// User
type A2 interface{
AddB(B2)
}
type B2 interface{}
func Main() {
var _ A2 = NewA() // error..
}
go interface type-conversion
go interface type-conversion
edited Nov 23 '18 at 9:29
Matthieu
asked Nov 21 '18 at 23:07
MatthieuMatthieu
105
105
That's probably not how interfaces are used in Go. I have t oadmit I have no idea what you are trying to do.
– Volker
Nov 22 '18 at 6:11
Ok, first this is not for a serious project, this is just me toying around. My goal here is to see if I can create an API with absolutely zero coupling what so ever using some kind of duck-typing. The user doesn't know anything about the provider and the provider doesn't know anything about the user, they are hosted on separated gits, and can't import from one another. The wiring is done by dependency-injection. The user tells what it needs (interface A2) and the provider what it provide (interface A). And I was hoping that A could be converted to A2 since the interfaces are the same.
– Matthieu
Nov 22 '18 at 10:01
add a comment |
That's probably not how interfaces are used in Go. I have t oadmit I have no idea what you are trying to do.
– Volker
Nov 22 '18 at 6:11
Ok, first this is not for a serious project, this is just me toying around. My goal here is to see if I can create an API with absolutely zero coupling what so ever using some kind of duck-typing. The user doesn't know anything about the provider and the provider doesn't know anything about the user, they are hosted on separated gits, and can't import from one another. The wiring is done by dependency-injection. The user tells what it needs (interface A2) and the provider what it provide (interface A). And I was hoping that A could be converted to A2 since the interfaces are the same.
– Matthieu
Nov 22 '18 at 10:01
That's probably not how interfaces are used in Go. I have t oadmit I have no idea what you are trying to do.
– Volker
Nov 22 '18 at 6:11
That's probably not how interfaces are used in Go. I have t oadmit I have no idea what you are trying to do.
– Volker
Nov 22 '18 at 6:11
Ok, first this is not for a serious project, this is just me toying around. My goal here is to see if I can create an API with absolutely zero coupling what so ever using some kind of duck-typing. The user doesn't know anything about the provider and the provider doesn't know anything about the user, they are hosted on separated gits, and can't import from one another. The wiring is done by dependency-injection. The user tells what it needs (interface A2) and the provider what it provide (interface A). And I was hoping that A could be converted to A2 since the interfaces are the same.
– Matthieu
Nov 22 '18 at 10:01
Ok, first this is not for a serious project, this is just me toying around. My goal here is to see if I can create an API with absolutely zero coupling what so ever using some kind of duck-typing. The user doesn't know anything about the provider and the provider doesn't know anything about the user, they are hosted on separated gits, and can't import from one another. The wiring is done by dependency-injection. The user tells what it needs (interface A2) and the provider what it provide (interface A). And I was hoping that A could be converted to A2 since the interfaces are the same.
– Matthieu
Nov 22 '18 at 10:01
add a comment |
1 Answer
1
active
oldest
votes
Go provides type checking as a feature, not a bug. When you declare B and B2 to be separate types, the compiler respects this distinction and treats them differently.
A familiar example is time.Duration
, which is just an int64
to count nanoseconds, but you cannot mix and match variables that are int64
and time.Duration
without an explicit type conversion. see time.Duration docs
Rather than trying to work around Go's type checking feature, you should try to learn how to express your algorithm using idiomatic Go.
The point here is to toy around and see the limit of the language, not about writing idiomatic go. (See my 1st comment on the question.) I was aware of the problems with redefining built-in types and with the slice of interfaces. But this is yet-another case where I can't implicitly convert from one interface to another...
– Matthieu
Nov 22 '18 at 10:06
@Matthieu Yes, this is intentional.
– Michael Hampton
Nov 23 '18 at 16:42
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421702%2fduck-typing-how-to-implicitly-convert-from-an-interface-to-another-interface-in%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Go provides type checking as a feature, not a bug. When you declare B and B2 to be separate types, the compiler respects this distinction and treats them differently.
A familiar example is time.Duration
, which is just an int64
to count nanoseconds, but you cannot mix and match variables that are int64
and time.Duration
without an explicit type conversion. see time.Duration docs
Rather than trying to work around Go's type checking feature, you should try to learn how to express your algorithm using idiomatic Go.
The point here is to toy around and see the limit of the language, not about writing idiomatic go. (See my 1st comment on the question.) I was aware of the problems with redefining built-in types and with the slice of interfaces. But this is yet-another case where I can't implicitly convert from one interface to another...
– Matthieu
Nov 22 '18 at 10:06
@Matthieu Yes, this is intentional.
– Michael Hampton
Nov 23 '18 at 16:42
add a comment |
Go provides type checking as a feature, not a bug. When you declare B and B2 to be separate types, the compiler respects this distinction and treats them differently.
A familiar example is time.Duration
, which is just an int64
to count nanoseconds, but you cannot mix and match variables that are int64
and time.Duration
without an explicit type conversion. see time.Duration docs
Rather than trying to work around Go's type checking feature, you should try to learn how to express your algorithm using idiomatic Go.
The point here is to toy around and see the limit of the language, not about writing idiomatic go. (See my 1st comment on the question.) I was aware of the problems with redefining built-in types and with the slice of interfaces. But this is yet-another case where I can't implicitly convert from one interface to another...
– Matthieu
Nov 22 '18 at 10:06
@Matthieu Yes, this is intentional.
– Michael Hampton
Nov 23 '18 at 16:42
add a comment |
Go provides type checking as a feature, not a bug. When you declare B and B2 to be separate types, the compiler respects this distinction and treats them differently.
A familiar example is time.Duration
, which is just an int64
to count nanoseconds, but you cannot mix and match variables that are int64
and time.Duration
without an explicit type conversion. see time.Duration docs
Rather than trying to work around Go's type checking feature, you should try to learn how to express your algorithm using idiomatic Go.
Go provides type checking as a feature, not a bug. When you declare B and B2 to be separate types, the compiler respects this distinction and treats them differently.
A familiar example is time.Duration
, which is just an int64
to count nanoseconds, but you cannot mix and match variables that are int64
and time.Duration
without an explicit type conversion. see time.Duration docs
Rather than trying to work around Go's type checking feature, you should try to learn how to express your algorithm using idiomatic Go.
answered Nov 22 '18 at 2:08
David JonesDavid Jones
6301512
6301512
The point here is to toy around and see the limit of the language, not about writing idiomatic go. (See my 1st comment on the question.) I was aware of the problems with redefining built-in types and with the slice of interfaces. But this is yet-another case where I can't implicitly convert from one interface to another...
– Matthieu
Nov 22 '18 at 10:06
@Matthieu Yes, this is intentional.
– Michael Hampton
Nov 23 '18 at 16:42
add a comment |
The point here is to toy around and see the limit of the language, not about writing idiomatic go. (See my 1st comment on the question.) I was aware of the problems with redefining built-in types and with the slice of interfaces. But this is yet-another case where I can't implicitly convert from one interface to another...
– Matthieu
Nov 22 '18 at 10:06
@Matthieu Yes, this is intentional.
– Michael Hampton
Nov 23 '18 at 16:42
The point here is to toy around and see the limit of the language, not about writing idiomatic go. (See my 1st comment on the question.) I was aware of the problems with redefining built-in types and with the slice of interfaces. But this is yet-another case where I can't implicitly convert from one interface to another...
– Matthieu
Nov 22 '18 at 10:06
The point here is to toy around and see the limit of the language, not about writing idiomatic go. (See my 1st comment on the question.) I was aware of the problems with redefining built-in types and with the slice of interfaces. But this is yet-another case where I can't implicitly convert from one interface to another...
– Matthieu
Nov 22 '18 at 10:06
@Matthieu Yes, this is intentional.
– Michael Hampton
Nov 23 '18 at 16:42
@Matthieu Yes, this is intentional.
– Michael Hampton
Nov 23 '18 at 16:42
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421702%2fduck-typing-how-to-implicitly-convert-from-an-interface-to-another-interface-in%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
That's probably not how interfaces are used in Go. I have t oadmit I have no idea what you are trying to do.
– Volker
Nov 22 '18 at 6:11
Ok, first this is not for a serious project, this is just me toying around. My goal here is to see if I can create an API with absolutely zero coupling what so ever using some kind of duck-typing. The user doesn't know anything about the provider and the provider doesn't know anything about the user, they are hosted on separated gits, and can't import from one another. The wiring is done by dependency-injection. The user tells what it needs (interface A2) and the provider what it provide (interface A). And I was hoping that A could be converted to A2 since the interfaces are the same.
– Matthieu
Nov 22 '18 at 10:01