猿问

Golang 在具有私有访问权限的结构中嵌入接口

我想以最惯用的方式在 Golang 中复制以下 Java 代码:


public class Handler {


    private Storage storage;

    private Mapper mapper;


    public Handler(Storage storage, Mapper mapper) {

        this.storage = storage;

        this.mapper = mapper;

    }


    public void handleKey(String k) {

        storage.put(k, mapper.map(k));

    }


}


interface Storage {

    public void put(String k, String v);

    public String get(String k);

}


@FunctionalInterface

interface Mapper {

    public String map(String a);

}


private static class InMemoryStorage implements Storage {

    private Map<String, String> table;


    public InMemoryStorage() {

        table = new HashMap<>();

    }


    public void put(String k, String v) {

        table.put(k, v);

    }


    public String get(String k) {

        return table.get(k);

    }

}

Handler类只公开方法handleKey。该类的行为通过传递不同的具体Storage和Mapper实现来参数化。


在阅读了effective Go - Embedding后,我认为这将是嵌入接口介绍结构的一个很好的用途。但我不知道如何避免将嵌入式接口的方法暴露给Handler用户。我可以做类似的事情


type Handler struct {

    store  Storage

    mapper Mapper

}


func (h Handler) Handle(k string) {

    h.store.Put(k, h.mapper.Map(k))

}


type Storage interface {

    Put(k string, v string)

    Get(k string) string

}


type Mapper interface {

    Map(k string) string

}


type inMemoryStorage {

    table map[string]string

}


func NewInMemoryStorage() Storage {

    return &inMemoryStore{table: make(map[string]string)}

}

但随后我无法将具体实现传递给Handler(创建结构文字),因为store和mapper未导出。我不想为每个可能的组合创建工厂方法......有什么建议吗?


侃侃尔雅
浏览 110回答 1
1回答

慕少森

这些不是嵌入的;嵌入在 Go 中具有特定含义,如规范中所述,以及您链接到的有效 Go 部分中的解释。它指的是未命名的字段,其字段和方法可以从其包含类型隐式访问。您的字段是命名的,而不是嵌入的。也就是说,您的两个结构体字段store和mapper不会导出,因此它们不会暴露给Handler定义的包之外的任何用户;在这方面你似乎已经有了你想要的行为。当您说必须“为每种可能的组合创建工厂方法”时,我不确定您的意思是什么 - 我认为没有任何必要的理由。您只需要一种工厂方法:func NewHandler(s Storage, m Mapper) Handler {    return Handler{store: s, mapper: m}}通过将适当的值传递给函数,可以将其Storage与 和的实现的任意组合一起使用。Mapper
随时随地看视频慕课网APP

相关分类

Go
我要回答