dongmou3615 2017-09-26 18:55
浏览 29

golang:在地图值中使用定义的接口

in the linked playground example, I define a type:

type DoMap map[int]func(Doer) string

Where Doer in an interface type that I define.

I implement the interface on a concrete type MyDoer. I'd like to be able to construct a DoMap where entries into that map contain functions like both of the following:

func(Doer) string // this works
func(*MyDoer) string // this doesn't
func(MyDoer) string // more-or-less the same idea, also doesn't

I can't, and although it's obvious they are different types, I wonder why I can't since function ensures I have to provide a MyDoer which implements Doer.

Isn't that enough to ensure I will fulfill my contract with the function?

Is there another way of achieving this?

https://play.golang.org/p/sJ2Rg3neL7

Update

Some comments are of the form "they are different" "that's the spec" but I can pass a MyDoer to a function that accepts a Doer - if the interface is implemented: why does putting it into a map change the result?

Update 2

There's a request to explain the "real problem" and a question of why I can't just use a map of types. I'll try best I can:

DoMap cannot be a map of types. I am writing a library that allows developers to succinctly define state machines, which succeed or fail to transition, based on the output of a developer written function (business logic) that accepts a developer defined type (business message). the library exists to ensure that the series of transitions can be serialized and recorded elsewhere and subsequently verified by third party users of the library. I didn't say all that originally, because it misses the point - there isn't a simple answer.

Now I feel like I am annoying everyone with my impertinent questions, and since I don't exactly have Rob Pike on speed dial, I'll probably delete this, unless some one is willing to trust that I need to do what I need to do, and suggest something.

  • 写回答

1条回答 默认 最新

  • dongwuge6201 2017-09-26 19:37
    关注

    You haven't outlined a concrete problem (the why). This makes it hard to suggest alternatives, because it looks like you're trying to recreate another language in go.

    In order of preference, you can use the type system as intended:

    type DoMap map[int]func(Doer) string
    
    type Doer interface {
        Do() int
        AlsoDo() int
    }
    

    https://play.golang.org/p/uPzoOZiLQG

    Or you can bypass the type system of course:

    type DoMap map[int]interface{}
    

    https://play.golang.org/p/lfKPkwhOGa

    But I wouldn't recommend that - better to work with the tools the language gives you, rather than trying to bend them out of shape.

    The intent of the interface is to advertise a contract about the functions - they require this of their argument, and no more. But then you also want to call AlsoDo on the argument, so if you want to do that, put it in the contract. Then all will work as you intend. The contract for the function should be published next to the function as in your example, it should be under your control.

    [EDIT] Finally, if you don't control the types passed in, perhaps you should rethink the idea of your map. It could be a map[int]Doer where Doer is an interface (which you should control). This lets you advertise what you require in your library, and users put whatever type they want in there (with whatever other dependencies they want).

    // Library 
    type DoMap map[int]Doer
    
    type Doer interface {
        Do() int
    }
    
    // Client 
    type MyDoer struct {
        myint int
    }
    
    func (d *MyDoer) Do() int {
        fmt.Println(d.AlsoDo())
        return d.myint + 1
    }
    
    func (d *MyDoer) AlsoDo() int {
        return d.myint + 2
    }
    

    https://play.golang.org/p/cs01C8bSKo

    [EDIT2] Final edit, if building an fsm management chain, you might find this little project inspirational. It should definitely be doable without much trouble, just not exactly as in your first attempt of a map of function which can take any type:

    https://github.com/ryanfaerman/fsm

    评论

报告相同问题?

悬赏问题

  • ¥50 potsgresql15备份问题
  • ¥15 Mac系统vs code使用phpstudy如何配置debug来调试php
  • ¥15 目前主流的音乐软件,像网易云音乐,QQ音乐他们的前端和后台部分是用的什么技术实现的?求解!
  • ¥60 pb数据库修改与连接
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上