Friday, April 26, 2024
HomeGolangProposal for dynamic implementation of interface - Technical Dialogue

Proposal for dynamic implementation of interface – Technical Dialogue


I wish to focus on a proposal for including the next reflection function to Go.

Given any Go interface sort, instantiate a Go worth that implements this interface, by passing every technique name and its arguments to a user-provided handler.

Some use instances for this function are:

Given any interface A that I take advantage of (presumably third celebration), I wish to time every technique name and log the calls and the occasions.

I might write code that given an interface A, and a struct S that implements A, it could implement HTTP REST consumer and server elements that implement interface A over HTTP, utilizing JSON to marshal technique arguments.

The server part would use A and S.
The consumer part would use solely A (the interface), and robotically create a struct that implements it. The server a part of this will already be performed. However the consumer can’t be performed presently, as a result of there isn’t any strategy to auto-generate one thing that implements an interface. I’d have to include a code generator that generates a consumer stub, which can have to be compiled within the consumer.

I’ve performed this, nevertheless it introduces an additional code technology step within the construct course of.

Java does this as follows:

bundle java.lang.replicate;

interface Invocation Handler {
   Object invoke(Object proxy,Technique technique,Object[] args)throws Throwable
}

class proxy {
  static newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
}

newProxyInstance() returns an object that implements all the required interfaces (not only one).

When a way of this object known as, it calls the offered InvocationHandler h.

You’ll be able to ignore ClassLoader. Go doesn’t load lessons dynamically so it doesn’t want a category loader.


bundle replicate

Worth.Name(in []Worth) []Worth

func StructOf(fields []StructField) Kind

The Go replicate bundle has a function that creates a struct sort given any []StructField created at runtime.
Java doesn’t have this.

I’m undecided precisely what strategies such a facility ought to have, however given the related Go options above and the Java implementation, I counsel one thing like this:


bundle replicate

ImplementationOf(h func(m Technique, in []Worth) []Worth, u Kind) any

Right here’s an entire instance of learn how to implement an interface wrapper that prints the execution time of every technique name, utilizing the above proposed function. It contains an implementation of the proposal that’s hardcoded to work for this instance solely.

https://play.golang.com/p/7trKj6TKHsB

bundle predominant

import (
	"fmt"
	"replicate"
	"time"
)

sort A interface {
	Add(n1, n2 int) int
}

sort S struct {
}

func (s *S) Add(n1, n2 int) int {
	return n1 + n2
}

sort TimingWrapper struct {
	Kind     replicate.Kind
	receiver replicate.Worth
}

func NewCallWrapper(receiver any) *TimingWrapper {
	var c TimingWrapper
	c.receiver = replicate.ValueOf(receiver)
	c.Kind = replicate.TypeOf(receiver)
	return &c
}

func (c *TimingWrapper) Handler(m replicate.Technique, in []replicate.Worth) []replicate.Worth {
	// m is the interface technique
	// we'd like the tactic for the receiver sort
	receiverMethod, okay := c.Kind.MethodByName(m.Title)
	if !okay {
		panic(fmt.Sprintf("no such technique: %s", m.Title))
	}
	// The interface technique doesn't have a receiver enter
	// We have to prepend one:
	rin := make([]replicate.Worth, 1, (1 + len(in)))
	rin[0] = c.receiver
	rin = append(rin, in...)

	begin := time.Now()
	out := receiverMethod.Func.Name(rin)
	period := time.Now().Sub(begin)
	fmt.Printf("%s: %vn", m.Title, period)
	return out
}

func predominant() {
	var a A = &S{}
	handler := NewCallWrapper(a).Handler
	var p *A
	v := /*replicate.*/ ImplementationOf(handler, replicate.TypeOf(p).Elem())
	a = v.(A)
	d := a.Add(1, 2)
	fmt.Printf("consequence: %dn", d)
}

// replicate.ImplementationOf doesn't exist,
// The code beneath is an implementation of it that's hardcoded to work for interface A.

sort aImpl struct {
	Kind    replicate.Kind
	Handler func(m replicate.Technique, in []replicate.Worth) []replicate.Worth
}

func (a *aImpl) Add(n1, n2 int) int {
	m, _ := a.Kind.MethodByName("Add")
	out := a.Handler(m, []replicate.Worth{replicate.ValueOf(n1), replicate.ValueOf(n2)})
	return int(out[0].Int())
}

func ImplementationOf(h func(m replicate.Technique, in []replicate.Worth) []replicate.Worth, u replicate.Kind) any {
	var p *A
	a := aImpl{Handler: h, Kind: replicate.TypeOf(p).Elem()}
	return &a
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments