Go 使用不同级别的接口
我正试图使用Go中的接口来组织代码 我有两个数据源:FTP和API。在每个源代码中,我都有几个结构,使逻辑根据情况而变化 在这个问题上,我将省略API并坚持使用FTP 我的问题来自于无法说:FTPAcq也是一项收购 如果Go 使用不同级别的接口,go,interface,Go,Interface,我正试图使用Go中的接口来组织代码 我有两个数据源:FTP和API。在每个源代码中,我都有几个结构,使逻辑根据情况而变化 在这个问题上,我将省略API并坚持使用FTP 我的问题来自于无法说:FTPAcq也是一项收购 如果FetchMeters(),当我执行ftp.Decrypt(nil)时,我希望ftp与FTPAcq“兼容” 这是我的密码: package main import ( "github.com/dutchcoders/goftp" log "github.com/
FetchMeters()
,当我执行ftp.Decrypt(nil)
时,我希望ftp与FTPAcq“兼容”
这是我的密码:
package main
import (
"github.com/dutchcoders/goftp"
log "github.com/sirupsen/logrus"
"os"
)
type Acquisition interface {
FetchMeters() ([]Meter, error)
Name() string
}
type FTPAcq interface {
Unzip(file string) string
Decrypt(file string) string
}
//type APIAcq interface {
// FetchMeter(meterID string) (Meter, error)
//}
func main() {
var acqs []Acquisition
ftp, err := NewFTPDriver(os.Getenv("FTP_USER"), os.Getenv("FTP_PASSWD"), os.Getenv("FTP_ADDR"), os.Getenv("FTP_PORT"))
if err != nil {
panic(err)
}
ftp1 := NewFTPDriverSGE(*ftp)
ftp2 := NewFTPDriverTA(*ftp)
acqs = append(acqs, ftp1, ftp2)
for _, acq := range acqs {
tmpMeters, err := acq.FetchMeters()
if err != nil {
log.Warn(acq.Name(), " got error :", err)
}
log.Info(tmpMeters)
}
}
type Meter struct {
ID string
OperationID string
Unit string
}
//FtpSGE is a implementation of acquisition Interface (see driver.go)
type FTP struct {
Username string
Password string
Url string
Port string
client *goftp.FTP
}
type FTPSGE struct {
FTP
}
type FTPTA struct {
FTP
}
func (f FTPSGE) Unzip(path string) []string {
return nil
}
func (f FTPTA) Unzip(path string) []string {
return nil
}
func (f FTPSGE) Decrypt(path string) []string {
return nil
}
func (f FTPTA) Decrypt(path string) []string {
return nil
}
func (ftp FTP) FetchMeters() ([]Meter, error) {
log.Info(ftp.Name(), " is running")
files := ftp.Download(nil)
files = ftp.Decrypt("") // I have several implementation of Decrypt
files = ftp.Unzip("") // I have several implementation of Unzip
log.Info(files)
return nil, nil
}
func (ftp FTP) Name() string {
panic("FTP ")
}
func (ftp FTP) Download(files []string) []string {
panic("implement me")
}
func NewFTPDriver(user, password, url, port string) (*FTP, error) {
var err error
ftp := &FTP{
Username: user,
Password: password,
Url: url,
Port: port,
}
if ftp.client, err = goftp.Connect(url + ":" + port); err != nil {
return nil, err
}
if err = ftp.client.Login(user, password); err != nil {
return nil, err
}
return ftp, nil
}
func NewFTPDriverSGE(f FTP) *FTPSGE {
return &FTPSGE{f}
}
func NewFTPDriverTA(f FTP) *FTPTA {
return &FTPTA{f}
}
就我而言,我得到:
ftp.Decrypt undefined (type FTP has no field or method Decrypt)
我该怎么办?
FTP
是否执行FTPAcq
。它只实现采集
。它甚至没有Decrypt()
作为方法、接口或非接口
FTPSGE
和FTPTA
实现FTPAcq
,但它们与FTP
的类型不同
我不知道你想做什么,但也许可以尝试在FTPSGE
和FTPTA
中嵌入FTP
。这为这两种类型提供了嵌入类型的字段和方法,并且仍然允许您在这些类型上定义其他方法(在您的案例中为FTPAcq
定义的方法)
比如说
类型FTPSGE{
文件传输协议
}
//或
类型FTPSGE{
*FTP
}
然后将其创建为:x:=FTPSGE{ftp1}
。请记住,这将在x
内部创建ftp1
的副本。如果ftp1
类型为FTP
(不是指针),则复制整个结构。如果ftp1
类型为*FTP
(一个指针,似乎就是您正在使用的),则会复制指针,并且x.FTP
仍然指向与ftp1
相同的数据
这意味着FTPSGE
将实现采集
和FTPAcq
您必须注意是否在值或指针上实现了接口:func(a)Something()
vsfunc(a*a)Somthing()
下面是一些关于方法、接口和嵌入的阅读
您试图对一个没有该方法的类型调用
Decrypt
。只能对实际具有这些方法的类型的值调用方法。请注意,这与接口无关。您可以同时删除它们,但仍然会得到相同的错误。