【问题标题】:Duck typing: How to implicitly convert from an interface to another interface in go鸭子打字:如何在go中隐式转换从一个接口到另一个接口
【发布时间】:2019-04-24 14:11:28
【问题描述】:

我是新手,我希望在用户和提供者之间使用(非常)松散耦合的 API 制作两个包。为此,我希望利用 go 的隐式实现接口和隐式转换的能力。

提供者和用户都有自己定义的接口(例如,提供者返回一个提供者.A,用户接受一个用户.A)。 使用这种模式,我可以从一种类型转换为另一种类型,而不是从另一个包中导入接口。

这适用于简单的接口,但是一旦方法将接口作为输入,从一种类型到另一种类型的转换就变得不可能了。

为什么不允许这种转换?有什么解决办法吗?

工作示例:

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()
}

导致问题的示例:

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 中使用接口的方式。我不得不承认我不知道你想做什么。
  • 好的,首先这不是一个严肃的项目,这只是我在玩弄。我的目标是看看我是否可以使用某种鸭子类型创建一个绝对零耦合的 API。用户对提供者一无所知,提供者对用户一无所知,它们托管在单独的 git 上,不能相互导入。接线是通过依赖注入完成的。用户告诉它需要什么(接口 A2)和提供者它提供什么(接口 A)。我希望 A 可以转换为 A2,因为接口是相同的。

标签: go interface type-conversion


【解决方案1】:

Go 将类型检查作为一项功能提供,而不是错误。当您将 B 和 B2 声明为单独的类型时,编译器会尊重这种区别并区别对待它们。

一个熟悉的例子是time.Duration,它只是一个用于计算纳秒的int64,但是如果没有显式类型转换,您不能混合和匹配int64time.Duration 的变量。 see time.Duration docs

与其尝试解决 Go 的类型检查功能,不如尝试学习如何使用惯用的 Go 来表达您的算法。

【讨论】:

  • 这里的重点是玩弄语言的极限,而不是写惯用的围棋。 (请参阅我对该问题的第一条评论。)我意识到重新定义内置类型和接口切片的问题。但这是我无法从一个接口隐式转换到另一个接口的另一种情况......
  • @Matthieu 是的,这是故意的。
猜你喜欢
  • 2018-07-16
  • 2021-07-22
  • 2023-03-25
  • 2011-06-26
  • 2019-08-31
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 2023-01-28
相关资源
最近更新 更多