godoc: https://golang.org/pkg/reflect/#Value.CanInterface
if !reflect.ValueOf(strct).Field(i).CanInterface() {
continue
}
if !reflect.ValueOf(strct).Field(i).CanInterface() {
continue
}
package main
import (
"context"
"fmt"
"math/rand"
"reflect"
"time"
)
func main() {
const numberOfTest = 10
soc := make([]reflect.SelectCase, numberOfTest)
channels := make([]chan int, numberOfTest)
for idx := range channels {
channels[idx] = make(chan int, 1)
}
for i := range soc {
soc[i] = reflect.SelectCase{
Dir: reflect.SelectRecv,
Chan: reflect.ValueOf(channels[i]),
}
}
ctx, cancel := context.WithCancel(context.Background())
go func() {
send := make(chan struct {
int
reflect.Value
bool
}, 1)
receive := send
go func() {
for {
// block call, could use a circuit breaker,
// e.g https://github.com/sony/gobreaker
idx, val, ok := reflect.Select(soc)
send <- struct {
int
reflect.Value
bool
}{idx, val, ok}
}
}()
for {
select {
case <-ctx.Done():
fmt.Println("bye~")
return
case payload := <-receive:
fmt.Printf("idx: %d, value: %v, bool: %t\n",
payload.int,
payload.Value,
payload.bool)
}
}
}()
go func() {
for {
for idx := range channels {
channels[idx] <- rand.Intn(100)
}
time.Sleep(3 * time.Second)
}
}()
time.Sleep(10 * time.Second)
cancel()
time.Sleep(3 * time.Second)
}
package main
import (
"fmt"
"reflect"
)
type A struct{ Name string }
type B struct{ Age int }
type C struct{ Address string }
func Merge(a interface{}, b interface{})( d interface{}) {
aType := reflect.TypeOf(a)
if aType.Kind() != reflect.Struct {
panic("a is not a struct")
}
bType := reflect.TypeOf(b)
if bType.Kind() != reflect.Struct {
panic("b is not a struct")
}
var fields []reflect.StructField
for i:=0 ; i< aType.NumField(); i++{
fields =append(fields, aType.Field(i))
}
for i:=0 ; i< bType.NumField(); i++{
fields =append(fields, bType.Field(i))
}
dType := reflect.StructOf(fields)
dVal := reflect.Indirect(reflect.New(dType))
aVal := reflect.ValueOf(a)
bVal := reflect.ValueOf(b)
for i := 0; i < aType.NumField(); i++ {
dVal.FieldByName(aType.Field(i).Name).Set(aVal.Field(i))
}
for i := 0; i < bType.NumField(); i++ {
dVal.FieldByName(bType.Field(i).Name).Set(bVal.Field(i))
}
d = dVal.Interface()
return
}
func main() {
a, b, c := A{"John"}, B{42}, C{"World"}
d1 := Merge(a, b)
d2 := Merge(a, c)
d3 := Merge(b, c)
fmt.Printf("%#v\n",d1)
fmt.Printf("%#v\n",d2)
fmt.Printf("%#v\n",d3)
}
package main
import "fmt"
type fun struct {
}
func (f *fun) run() {
fmt.Println("stateless member function call.")
}
type I interface {
run()
}
func main() {
I((*fun)(nil)).run()
}
#include <iostream>
struct fun {
void run()
{
using std::cout;
using std::endl;
cout << "stateless member function call." << endl;
}
};
int main()
{
static_cast<fun*>(nullptr)->run();
}
using INT = int; INT i1 = 42; int i2 = i1;
package main
type INT int
func main() {
var i1 INT = 42
var i2 int = int(i1)
_ = i2
}
// if !ok, v is int's default value, which is 0 v, ok := any.(int) // if !ok, v is interface_1's default value, which is nil v, ok := any.(interface_1)and this failed at run-time if conversion failed:
// run-time error: panic: interface conversion: interface {} is int64, not int
v := any.(int)
// run-time error: panic: interface conversion: interface {} is interface_2,
// not interface_1, which lack member functions.
v := any.(interface_1)
var x float64 = 3.4
// the interface{} has a copy of value x.
v := reflect.ValueOf(x)
// Error: will panic. It's not setting the x, but the copy of it.
v.SetFloat(7.1)
var x float64 = 3.4
// Note: take the address of x.
p := reflect.ValueOf(&x)
// *float64
fmt.Println("type of p:", p.Type())
// false?! Why? Because we do not want to set p, but *p
fmt.Println("settability of p:", p.CanSet())
v := p.Elem()
// true
fmt.Println("settability of v:", v.CanSet())
Same in C/C++, as long as we have the struct instance's address, we can modify it's fields.type T struct {
A int // Must be exported, thus upper case.
B string // Must be exported, thus upper case.
}
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}