I have this type implementation:
type A struct{
name string
}
func (a A) getName() string {
return "My name is " + a.name
}
How I can change implementation of method getName() for this type using reflection? For example, I want use next implementation instead of current:
func newGetName() string {
return "test reflection"
}
Anyway, reflection does not allow you to change code behaviour, it can only explore current code, invoke methods and constuctors, change fields values, that kind of things. If you want to actually change the behaviour of a method you would have to use a bytecode manipulation library such as ASM.
ReflectionTestUtils is a part of Spring Test Context framework. It is a collection for reflection-based utility methods used in a unit, and integration testing scenarios to set the non-public fields, invoke non-public methods, and inject dependencies.
It is a collection for reflection-based utility methods used in a unit, and integration testing scenarios to set the non-public fields, invoke non-public methods, and inject dependencies. In this tutorial, we'll take a look at how we can use the ReflectionTestUtils in unit testing by going through several examples.
There exists a couple of frameworks that allows you to dynamically change any method at runtime: Harmony Free and Open Source (MIT)! Prig: Free and Open Source (MIT), requires Visual Studio extension and running programs under a launcher, not updated since 2017.
Go is a compiled language. As such, it's not possible to modify the implementation of things at runtime. What you can do is changing the place function pointers point to:
var getName func(string) = func(name string) {
return "my name is " + name
}
In order to make this work with a structure, you have to resort to a few tricks. First add getName
as a member to A
:
type A struct {
name string
getName func() string
}
Then we enclose a pointer to the structure as an implicit (i.e. closed over) parameter:
foo := &A{name: "Hans"}
foo.getName = func() string {
return "my name is " + name
}
Now you can call A.getName()
and the result is "my name is hans"
. You can use method expressions and many other features just fine, but getName
is a structure member and not a method of A
, so keep this in mind. When you want to give a new meaning to getName
, assign something different to it:
foo.getName = func() string {
return "test reflection"
}
Another idea that is especially applicable if you know in advance what implementations getName
could have is to add a new member to A
that says what implementation getName
currently has and then switch over this variable.
Note the idiomatic Go is to not do that and use interface instead:
See this example:
package main
import "fmt"
type Aer interface {
getName() string
}
type A struct {
name string
}
func (a A) getName() string {
return "My name is " + a.name
}
type testA struct {
a A
}
func (ta testA) getName() string {
return "NEW: My name is " + ta.a.name
}
func main() {
a := A{name: "nameA"}
fmt.Println(a.getName())
ta := testA{a: a}
fmt.Println(ta.getName())
}
Output:
My name is nameA
NEW: My name is nameA
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With