在Go语言中,如何隔离返回多个原语值的包呢?

mwngjboj  于 2023-03-21  发布在  Go
关注(0)|答案(1)|浏览(126)

如果我有一个requests包,它用GetText方法定义了一个TextExtractor接口,GetText方法返回Text类型,那么实现必须 * 完全 * 满足TextExtractor约定,并且它们被强制导入Text类型。
我有两种可能的TextExtractor实现--一种使用AWS Comprehend,另一种使用AWS Textract。

文件 aws_理解.go

package aws_comprehend

type AwsComprehend struct{}

func (a *AwsComprehend) GetText() *Text {
    // do some stuff with aws comprehend...
    return &Text{
        Text:     "text",
        Language: "language",
    }
}

type Text struct {
    Text string
    Language string
}

文件 * 请求.go*

package requests

import "fmt"

type TextExtractor interface {
    GetText() *Text
}

type Text struct {
    Text     string
    Language string
}

func HandleRequest(textExtractor TextExtractor) {
    text := textExtractor.GetText()
    fmt.Println(text)
}

文件 main.go

package main

import (
    "aws_comprehend"
    "requests"
)

func main() {
    textExtractor := new(aws_comprehend.AwsComprehend)

    requests.HandleRequest(textExtractor)
    // this does not work:
    // cannot use textExtractor (variable of type *aws_comprehend.AwsComprehend) as
    //         requests.TextExtractor value in argument to requests.HandleRequest:
    //         *aws_comprehend.AwsComprehend does not implement requests.TextExtractor
    //         (wrong type for method GetText)
    //     have GetText() *aws_comprehend.Text
    //     want GetText() *requests.Text
}

我理解为什么这行不通,因为Go语言不支持协变结果类型,但我的问题是,这种情况下的标准编码方式是什么?Go语言提供了隐式接口,这意味着隔离包非常容易:调用包定义了它所使用的接口,并且它被传递了实现这些接口的实现。这意味着**包根本不需要相互引用。但是如果一个包定义了一个接口,它返回的不仅仅是一个原语值,那么你必须故意共享这些值类型。如果GetText返回一个string,上面的代码就可以了。但是它返回一个struct或其他接口的事实,意味着代码不能用这种方式编写。
我希望requests包不知道任何关于aws_comprehend包的信息,这是因为我有两个TextExtractor接口的实现:一个使用AWS Comprehend,另一个使用AWS Textract。我 * 也 * 不希望包含一个“中间”包,该包具有requests包和aws_comprehend包都继承的接口。如果两个包必须继承相同的接口,那么它看起来就像是间接耦合到我,它破坏了隐式接口的想法。
我明白围棋很固执己见,那么解决这个问题的标准方法是什么呢?

mtb9vblg

mtb9vblg1#

首先,你的文件布局是无效的。你不能有两个文件在同一个文件夹中,不同的包。所以下面是一个正确的布局。我也删除了所有的指针,因为他们不需要这个例子,只是分散注意力。
最后,我更新了该方法以返回正确的类型,以便代码实际编译:
aws_comprehend/aws_comprehend.go

package aws_comprehend

import "hello/requests"

type AwsComprehend struct{}

func (AwsComprehend) GetText() requests.Text {
   return requests.Text{}
}

requests/request.go

package requests

import "fmt"

type TextExtractor interface {
   GetText() Text
}

type Text struct {
   Language string
   Text     string
}

func HandleRequest(textExtractor TextExtractor) {
   text := textExtractor.GetText()
   fmt.Println(text)
}

main.go

package main

import (
   "hello/aws_comprehend"
   "hello/requests"
)

func main() {
   var textExtractor aws_comprehend.AwsComprehend
   requests.HandleRequest(textExtractor)
}

相关问题