Hi,

no, there isn't really a solution to this. I've blogged about this:
https://blog.merovius.de/2017/07/30/the-trouble-with-optional-interfaces.html
A combination of generics and embedding can help. So, you can do

type Wrapper[T] struct {
    T
    otherFields
}

func (w *Wrapper) SomeNewMethod() {
}

But even then, you need to know the static type of what you're wrapping (so
http Middleware, for example, couldn't use this).

I'm also not super sure if it's a good idea to do this even if you could.
An interface might contain multiple, interdependent methods. As an example,
`http.ResponseWriter` implicitly calls `WriteHeader` the first time you
call `Write`. So, if you wrap a `ResponseWriter` and overwrite
`WriteHeader`, that overwritten method has to be called explicitly (the
underlying `ResponseWriter` will call its own `WriteHeader`). So if you
don't know what the methods of the wrapped type are and do, you might
introduce very hard to find bugs.

On Wed, Aug 26, 2020 at 5:49 PM cpu...@gmail.com <cpui...@gmail.com> wrote:

> Hi All,
>
> using interfaces for behavioural testing seems a common pattern in go:
>
>     if typed, hasCapability := d.(Capability); hasCapability...
>
> I have the requirement to dynamically compose interfaces at runtime, i.e.
> I cannot know upfront which set of interfaces a resulting type will support:
>
>     type resultingType interface {
>         basicCapability
>         ...any combination of additional capabilities
>     }
>
> If there is only a single additional/optional capability to implement that
> is simple to solve, e.g. by implementing a wrapping struct that embeds the
> basic capability and adds an additional capability. Applying this pattern
> across multiple layers (stack of wrapping structs does not work as the
> embedded interfaces don't bubble up).
>
> However, the number of additional capabilities that a type might have to
> support could be bigger (think of physical meters which could supply power,
> energy, currents, frequency etc).
>
> I'm solved this by using go:generate which is fed the basic and set of
> optional types and generates additional types for any _combination_ of
> additional types, an example is attached (and source at
> https://github.com/andig/evcc/pull/310/files#diff-fa40c05651b4682eb25a198f8a4a98f0).
> This is similar to the "old" pattern of simulation generics via generated
> code.
>
> I'm wondering if using a pattern of dynamic composition is sound, if the
> the go:generate approach is a good one or if there are better ways?
>
> Kind regards,
> Andi
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/217cee40-1e00-442d-a4d2-7d4a37e41544n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/217cee40-1e00-442d-a4d2-7d4a37e41544n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEQq%2BErDOGbX5jD1PrnZQdrYut_E6zajRpYYbM3NiBe1g%40mail.gmail.com.

Reply via email to