首页 > 解决方案 > 类型断言与导入接口

问题描述

我正在开展一个项目,该项目需要对某些数据进行某种程度的抽象,并且我希望使使用数据的包尽可能独立,以便将来可以交换。

这是我想到的两种可能的方式,一种是拥有一个通用的数据接口并让所有地方都导入它。另一种是让每个包定义自己的接口并进行类型断言。

哪种方式是最常用的?

// 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
}

标签: gointerface

解决方案


这是要记住的简单规则。应在要接收该接口类型的包中声明接口类型。为了满足接口,您不必导入它。您需要做的就是声明接口指定的方法。

什么时候使用接口?通常,当您有一个字段或参数时,您希望能够接受多种数据类型,并且您可以通过调用方法来完成您需要做的所有事情。您如何确定界面中的内容?您只需问自己:“我需要调用什么方法来调用这个值来使用它?”

在您的示例中,唯一看似有意义的方法是myint() int,而且您打算使用它的唯一地方是 in Service

type Service struct {
   extractor interface {
      myint() int
   }
}

func (s Service) serve() {
    s.extractor.myint()
}

推荐阅读