go - 类型断言与导入接口
问题描述
我正在开展一个项目,该项目需要对某些数据进行某种程度的抽象,并且我希望使使用数据的包尽可能独立,以便将来可以交换。
这是我想到的两种可能的方式,一种是拥有一个通用的数据接口并让所有地方都导入它。另一种是让每个包定义自己的接口并进行类型断言。
哪种方式是最常用的?
// Importing interface
// src/model
type IData interface {
myint() int
}
// src/dataextractor
import src/model
type DataExtractor struct {
foo() IData
}
// src/service
import src/model
type ServiceDataExtractor interface {
foo() IData
}
type Service struct {
extractor ServiceDataExtractor
}
func (s Service) serve() {
v = s.extractor.foo()
// do stuff with v
}
对比
// type assertion
// src/dataextractor
type DataExtractorData struct{}
func (d DataExtractorData) myint()int {}
type DataExtractor struct {
foo() interface{} {
reutrn DataExtractorData{}
}
}
// src/service
type ServiceData interface {
myint() int
}
type ServiceDataExtractor interface {
foo() interface{}
}
type Service struct {
extractor ServiceDataExtractor
}
func (s Service) serve() {
data := s.extractor.foo()
v, ok := data.(ServiceData)
// do stuff with v
}
解决方案
这是要记住的简单规则。应在要接收该接口类型的包中声明接口类型。为了满足接口,您不必导入它。您需要做的就是声明接口指定的方法。
什么时候使用接口?通常,当您有一个字段或参数时,您希望能够接受多种数据类型,并且您可以通过调用方法来完成您需要做的所有事情。您如何确定界面中的内容?您只需问自己:“我需要调用什么方法来调用这个值来使用它?”
在您的示例中,唯一看似有意义的方法是myint() int
,而且您打算使用它的唯一地方是 in Service
。
type Service struct {
extractor interface {
myint() int
}
}
func (s Service) serve() {
s.extractor.myint()
}
推荐阅读
- php - 在调用使用命名空间的类时,你能避免指定命名空间吗?
- python - 有没有办法匹配来自两个数据帧的序列号并将 df2 中的系列(来自行)列表添加到 df1 中的新列(Python,pandas)
- android - 如何使用 Android Studio Translations Editor 翻译字符串数组
- laravel - 无法使用 composer 将“laravel/ui”安装到 Laravel 8 项目中
- python - 如何打印python循环内的图像名称并将所有打印结果导出到excel
- mysql - mysql select函数运行两次
- deep-learning - 暗网和数据增强
- hlsl - 直接 2D HLSL 像素着色器坐标空间
- excel-formula - Excel:如何将“答案”行移动到“问题”列下?
- c# - 连接两个保存为 blob 的 PDF 文件