dragon_9000 2019-09-04 15:47
浏览 121


I want to replicate the following Java code in Golang in the most idiomatic way possible:

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);

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 class only exposes the method handleKey. The behaviour of this class is parametrized by passing different concrete Storage and Mapper implementations.

After reading Effective Go - Embedding, I thought this would be a good use of embedding interfaces intro structs. But I can't figure out how to avoid exposing the embedded interfaces' methods to Handler users. I can do something like

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

but then I cannot pass concrete implementations to the Handler (creating struct literal) because store and mapper are unexported. And I do not want to create factory methods for each possible combination... Any suggestions?

  • 写回答

1条回答 默认 最新

  • dongmei9961 2019-09-04 15:58

    Those are not embedded; embedding has a specific meaning in Go, as outlined in the spec, and as explained in the Effective Go section you linked to. It refers to unnamed fields, whose fields and methods are accessible implicitly from their containing type. Your fields are named, not embedded.

    That said, your two struct fields, store and mapper, are not exported, so they will not be exposed to any user outside the package in which Handler is defined; you seem to already have your desired behavior in that regard.

    I'm not sure what you mean when you say you would have to "create factory methods for each possible combination" - I don't see any reason that would be necessary. You need only one factory method:

    func NewHandler(s Storage, m Mapper) Handler {
        return Handler{store: s, mapper: m}

    Which could be used with any combination of implementations of Storage and Mapper by passing appropriate values to the function.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?



  • ¥15 微信公众号如何开发网页
  • ¥15 h3.6m 人类行为预测论文复现
  • ¥50 wordpress项目注册报失败刷新后其实是成功状态,请求排查原因
  • ¥20 linxu服务器僵尸进程不释放,代码如何修改?
  • ¥15 pycharm激活不成功
  • ¥40 如果update 一个列名为参数的value
  • ¥15 基于51单片机的水位检测系统设计中LCD1602一直不显示
  • ¥15 OCS2安装出现问题,请大家给点意见
  • ¥15 ros小车启动launch文件报错
  • ¥15 vs2015到期想登陆但是登陆不上