{"id":16939599,"url":"https://github.com/a8m/reflect-examples","last_synced_at":"2025-04-05T14:09:32.201Z","repository":{"id":50337511,"uuid":"117007447","full_name":"a8m/reflect-examples","owner":"a8m","description":"Bunch of examples for dealing with the reflect package","archived":false,"fork":false,"pushed_at":"2021-07-09T13:22:46.000Z","size":75,"stargazers_count":563,"open_issues_count":2,"forks_count":76,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-29T13:11:32.724Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a8m.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-10T20:30:10.000Z","updated_at":"2025-03-24T12:49:37.000Z","dependencies_parsed_at":"2022-09-17T23:12:12.066Z","dependency_job_id":null,"html_url":"https://github.com/a8m/reflect-examples","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a8m%2Freflect-examples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a8m%2Freflect-examples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a8m%2Freflect-examples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a8m%2Freflect-examples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a8m","download_url":"https://codeload.github.com/a8m/reflect-examples/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345855,"owners_count":20924102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T21:05:07.127Z","updated_at":"2025-04-05T14:09:32.185Z","avatar_url":"https://github.com/a8m.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg \n    src=\"img/logo.png\"\n    width=\"500\" alt=\"Golang reflect package examples\"\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\u003c/p\u003e\n\nThis repository contains a bunch of examples for dealing with the `reflect` package.\nMainly, for decoding/encoding stuff, and calling functions dynamically.  \nMost of the examples were taken from projects I worked on in the past, and some from projects I am currently working on.  \n\nYou will also find informative comments in the examples, that will help you to understand the code.\nsome of them are mine, and some of them were taken from the godoc website.\n\nIf you want to contribute to this repository, don't hesitate to create a PR.\n\nThe awesome gopher in the logo was taken from [@egonelbre/gophers](https://github.com/egonelbre/gophers).\n\n\n### Table Of Content\n- [Read struct tags](#read-struct-tags)\n- [Get and set struct fields](#get-and-set-struct-fields)\n- [Fill slice with values](#fill-slice-with-strings-without-knowing-its-type-use-case-decoder)\n- [Set a value of a number](#set-a-value-of-a-number-use-case-decoder)\n- [Decode key-value pairs into map](#decode-key-value-pairs-into-map)\n- [Decode key-value pairs into struct](#decode-key-value-pairs-into-struct)\n- [Encode struct into key-value pairs](#encode-struct-into-key-value-pairs)\n- [Check if the underlying type implements an interface](#check-if-the-underlying-type-implements-an-interface)\n- [Wrap a `reflect.Value` with pointer (`T` =\u003e `*T`)](#wrap-a-reflectvalue-with-pointer-t--t)\n- [Function calls](#function-calls)\n  - [Call to a method without prameters, and without return value](#call-method-without-prameters-and-without-return-value)\n  - [Call to a function with list of arguments, and validate return values](#call-function-with-list-of-arguments-and-validate-return-values)\n  - [Call to a function dynamically. similar to the template/text package](#call-to-a-function-dynamically-similar-to-the-templatetext-package)\n  - [Call to a function with variadic parameter](#call-function-with-variadic-parameter)\n  - [Create function at runtime](#create-function-at-runtime)\n\n### Read struct tags\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype User struct {\n\tEmail  string `mcl:\"email\"`\n\tName   string `mcl:\"name\"`\n\tAge    int    `mcl:\"age\"`\n\tGithub string `mcl:\"github\" default:\"a8m\"`\n}\n\nfunc main() {\n\tvar u interface{} = User{}\n\t// TypeOf returns the reflection Type that represents the dynamic type of u.\n\tt := reflect.TypeOf(u)\n\t// Kind returns the specific kind of this type. \n\tif t.Kind() != reflect.Struct {\n\t\treturn\n\t}\n\tfor i := 0; i \u003c t.NumField(); i++ {\n\t\tf := t.Field(i)\n\t\tfmt.Println(f.Tag.Get(\"mcl\"), f.Tag.Get(\"default\"))\n\t}\n}\n```\nCalling to `Kind()` can returns one of [this list](https://golang.org/pkg/reflect/#Kind).\n\n### Get and set struct fields\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype User struct {\n\tEmail  string `mcl:\"email\"`\n\tName   string `mcl:\"name\"`\n\tAge    int    `mcl:\"age\"`\n\tGithub string `mcl:\"github\" default:\"a8m\"`\n}\n\nfunc main() {\n\tu := \u0026User{Name: \"Ariel Mashraki\"}\n\t// Elem returns the value that the pointer u points to.\n\tv := reflect.ValueOf(u).Elem()\n\tf := v.FieldByName(\"Github\")\n\t// make sure that this field is defined, and can be changed.\n\tif !f.IsValid() || !f.CanSet() {\n\t\treturn\n\t}\n\tif f.Kind() != reflect.String || f.String() != \"\" {\n\t\treturn\n\t}\n\tf.SetString(\"a8m\")\n\tfmt.Printf(\"Github username was changed to: %q\\n\", u.Github)\n}\n```\n\n### Fill slice with strings, without knowing its type. Use case: decoder.\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n)\n\nfunc main() {\n\tvar (\n\t\ta []string\n\t\tb []interface{}\n\t\tc []io.Writer\n\t)\n\tfmt.Println(fill(\u0026a), a) // pass\n\tfmt.Println(fill(\u0026b), b) // pass\n\tfmt.Println(fill(\u0026c), c) // fail\n}\n\nfunc fill(i interface{}) error {\n\tv := reflect.ValueOf(i)\n\tif v.Kind() != reflect.Ptr {\n\t\treturn fmt.Errorf(\"non-pointer %v\", v.Type())\n\t}\n\t// get the value that the pointer v points to.\n\tv = v.Elem()\n\tif v.Kind() != reflect.Slice {\n\t\treturn fmt.Errorf(\"can't fill non-slice value\")\n\t}\n\tv.Set(reflect.MakeSlice(v.Type(), 3, 3))\n\t// validate the type of the slice. see below.\n\tif !canAssign(v.Index(0)) {\n\t\treturn fmt.Errorf(\"can't assign string to slice elements\")\n\t}\n\tfor i, w := range []string{\"foo\", \"bar\", \"baz\"} {\n\t\tv.Index(i).Set(reflect.ValueOf(w))\n\t}\n\treturn nil\n}\n\n// we accept strings, or empty interfaces.\nfunc canAssign(v reflect.Value) bool {\n\treturn v.Kind() == reflect.String || (v.Kind() == reflect.Interface \u0026\u0026 v.NumMethod() == 0)\n}\n```\n\n### Set a value of a number. Use case: decoder. \n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\nconst n = 255\n\nfunc main() {\n\tvar (\n\t\ta int8\n\t\tb int16\n\t\tc uint\n\t\td float32\n\t\te string\n\t)\n\tfmt.Println(fill(\u0026a), a)\n\tfmt.Println(fill(\u0026b), b)\n\tfmt.Println(fill(\u0026c), c)\n\tfmt.Println(fill(\u0026d), c)\n\tfmt.Println(fill(\u0026e), e)\n}\n\nfunc fill(i interface{}) error {\n\tv := reflect.ValueOf(i)\n\tif v.Kind() != reflect.Ptr {\n\t\treturn fmt.Errorf(\"non-pointer %v\", v.Type())\n\t}\n\t// get the value that the pointer v points to.\n\tv = v.Elem()\n\tswitch v.Kind() {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tif v.OverflowInt(n) {\n\t\t\treturn fmt.Errorf(\"can't assign value due to %s-overflow\", v.Kind())\n\t\t}\n\t\tv.SetInt(n)\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\tif v.OverflowUint(n) {\n\t\t\treturn fmt.Errorf(\"can't assign value due to %s-overflow\", v.Kind())\n\t\t}\n\t\tv.SetUint(n)\n\tcase reflect.Float32, reflect.Float64:\n\t\tif v.OverflowFloat(n) {\n\t\t\treturn fmt.Errorf(\"can't assign value due to %s-overflow\", v.Kind())\n\t\t}\n\t\tv.SetFloat(n)\n\tdefault:\n\t\treturn fmt.Errorf(\"can't assign value to a non-number type\")\n\t}\n\treturn nil\n}\n```\n\n### Decode key-value pairs into map\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\tvar (\n\t\tm0 = make(map[int]string)\n\t\tm1 = make(map[int64]string)\n\t\tm2 map[interface{}]string\n\t\tm3 map[interface{}]interface{}\n\t\tm4 map[bool]string\n\t)\n\ts := \"1=foo,2=bar,3=baz\"\n\tfmt.Println(decodeMap(s, \u0026m0), m0) // pass\n\tfmt.Println(decodeMap(s, \u0026m1), m1) // pass\n\tfmt.Println(decodeMap(s, \u0026m2), m2) // pass\n\tfmt.Println(decodeMap(s, \u0026m3), m3) // pass\n\tfmt.Println(decodeMap(s, \u0026m4), m4) // fail\n}\n\nfunc decodeMap(s string, i interface{}) error {\n\tv := reflect.ValueOf(i)\n\tif v.Kind() != reflect.Ptr {\n\t\treturn fmt.Errorf(\"non-pointer %v\", v.Type())\n\t}\n\t// get the value that the pointer v points to.\n\tv = v.Elem()\n\tt := v.Type()\n\t// allocate a new map, if v is nil. see: m2, m3, m4.\n\tif v.IsNil() {\n\t\tv.Set(reflect.MakeMap(t))\n\t}\n\t// assume that the input is valid.\n\tfor _, kv := range strings.Split(s, \",\") {\n\t\ts := strings.Split(kv, \"=\")\n\t\tn, err := strconv.Atoi(s[0])\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse number: %v\", err)\n\t\t}\n\t\tk, e := reflect.ValueOf(n), reflect.ValueOf(s[1])\n\t\t// get the type of the key.\n\t\tkt := t.Key()\n\t\tif !k.Type().ConvertibleTo(kt) {\n\t\t\treturn fmt.Errorf(\"can't convert key to type %v\", kt.Kind())\n\t\t}\n\t\tk = k.Convert(kt)\n\t\t// get the element type.\n\t\tet := t.Elem()\n\t\tif et.Kind() != v.Kind() \u0026\u0026 !e.Type().ConvertibleTo(et) {\n\t\t\treturn fmt.Errorf(\"can't assign value to type %v\", kt.Kind())\n\t\t}\n\t\tv.SetMapIndex(k, e.Convert(et))\n\t}\n\treturn nil\n}\n```\n\n### Decode key-value pairs into struct\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n)\n\ntype User struct {\n\tName    string\n\tGithub  string\n\tprivate string\n}\n\nfunc main() {\n\tvar (\n\t\tv0 User\n\t\tv1 *User\n\t\tv2 = new(User)\n\t\tv3 struct{ Name string }\n\t\ts  = \"Name=Ariel,Github=a8m\"\n\t)\n\tfmt.Println(decode(s, \u0026v0), v0) // pass\n\tfmt.Println(decode(s, v1), v1)  // fail\n\tfmt.Println(decode(s, v2), v2)  // pass\n\tfmt.Println(decode(s, v3), v3)  // fail\n\tfmt.Println(decode(s, \u0026v3), v3) // pass\n}\n\nfunc decode(s string, i interface{}) error {\n\tv := reflect.ValueOf(i)\n\tif v.Kind() != reflect.Ptr || v.IsNil() {\n\t\treturn fmt.Errorf(\"decode requires non-nil pointer\")\n\t}\n\t// get the value that the pointer v points to.\n\tv = v.Elem()\n\t// assume that the input is valid.\n\tfor _, kv := range strings.Split(s, \",\") {\n\t\ts := strings.Split(kv, \"=\")\n\t\tf := v.FieldByName(s[0])\n\t\t// make sure that this field is defined, and can be changed.\n\t\tif !f.IsValid() || !f.CanSet() {\n\t\t\tcontinue\n\t\t}\n\t\t// assume all the fields are type string.\n\t\tf.SetString(s[1])\n\t}\n\treturn nil\n}\n```\n\n### Encode struct into key-value pairs\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n)\n\ntype User struct {\n\tEmail   string `kv:\"email,omitempty\"`\n\tName    string `kv:\"name,omitempty\"`\n\tGithub  string `kv:\"github,omitempty\"`\n\tprivate string\n}\n\nfunc main() {\n\tvar (\n\t\tu = User{Name: \"Ariel\", Github: \"a8m\"}\n\t\tv = struct {\n\t\t\tA, B, C string\n\t\t}{\n\t\t\t\"foo\",\n\t\t\t\"bar\",\n\t\t\t\"baz\",\n\t\t}\n\t\tw = \u0026User{}\n\t)\n\tfmt.Println(encode(u))\n\tfmt.Println(encode(v))\n\tfmt.Println(encode(w))\n}\n\n// this example supports only structs, and assume their\n// fields are type string.\nfunc encode(i interface{}) (string, error) {\n\tv := reflect.ValueOf(i)\n\tt := v.Type()\n\tif t.Kind() != reflect.Struct {\n\t\treturn \"\", fmt.Errorf(\"type %s is not supported\", t.Kind())\n\t}\n\tvar s []string\n\tfor i := 0; i \u003c t.NumField(); i++ {\n\t\tf := t.Field(i)\n\t\t// Skip unexported fields. As mentioned in GoDoc:\n\t\t// PkgPath is the package path that qualifies a lower case (unexported)\n\t\t// field name. It is empty for upper case (exported) field names.\n\t\t// For Go version \u003e= 1.17, use the StructField.IsExported function instead.\n\t\tif f.PkgPath != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tfv := v.Field(i)\n\t\tkey, omit := readTag(f)\n\t\t// skip empty values when \"omitempty\" set.\n\t\tif omit \u0026\u0026 fv.String() == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\ts = append(s, fmt.Sprintf(\"%s=%s\", key, fv.String()))\n\t}\n\treturn strings.Join(s, \",\"), nil\n}\n\nfunc readTag(f reflect.StructField) (string, bool) {\n\tval, ok := f.Tag.Lookup(\"kv\")\n\tif !ok {\n\t\treturn f.Name, false\n\t}\n\topts := strings.Split(val, \",\")\n\tomit := false\n\tif len(opts) == 2 {\n\t\tomit = opts[1] == \"omitempty\"\n\t}\n\treturn opts[0], omit\n}\n```\n\n### Check if the underlying type implements an interface\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype Marshaler interface {\n\tMarshalKV() (string, error)\n}\n\ntype User struct {\n\tEmail   string `kv:\"email,omitempty\"`\n\tName    string `kv:\"name,omitempty\"`\n\tGithub  string `kv:\"github,omitempty\"`\n\tprivate string\n}\n\nfunc (u User) MarshalKV() (string, error) {\n\treturn fmt.Sprintf(\"name=%s,email=%s,github=%s\", u.Name, u.Email, u.Github), nil\n}\n\nfunc main() {\n\tfmt.Println(encode(User{\"boring\", \"Ariel\", \"a8m\", \"\"}))\n\tfmt.Println(encode(\u0026User{Github: \"posener\", Name: \"Eyal\", Email: \"boring\"}))\n}\n\nvar marshalerType = reflect.TypeOf(new(Marshaler)).Elem()\n\nfunc encode(i interface{}) (string, error) {\n\tt := reflect.TypeOf(i)\n\tif !t.Implements(marshalerType) {\n\t\treturn \"\", fmt.Errorf(\"encode only supports structs that implement the Marshaler interface\")\n\t}\n\tm, _ := reflect.ValueOf(i).Interface().(Marshaler)\n\treturn m.MarshalKV()\n}\n```\n\n### Wrap a `reflect.Value` with pointer (`T` =\u003e `*T`)\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype User struct {\n\tName string\n}\n\nfunc main() {\n\t// T =\u003e *T\n\tu1 := User{\"a8m\"}\n\tp1 := ptr(reflect.ValueOf(u1))\n\tfmt.Println(u1 == p1.Elem().Interface())\n\n\t// *T =\u003e **T\n\tu2 := \u0026User{\"a8m\"}\n\tp2 := ptr(reflect.ValueOf(u2))\n\tfmt.Println(*u2 == p2.Elem().Elem().Interface())\n}\n\n// ptr wraps the given value with pointer: V =\u003e *V, *V =\u003e **V, etc.\nfunc ptr(v reflect.Value) reflect.Value {\n\tpt := reflect.PtrTo(v.Type()) // create a *T type.\n\tpv := reflect.New(pt.Elem())  // create a reflect.Value of type *T.\n\tpv.Elem().Set(v)              // sets pv to point to underlying value of v.\n\treturn pv\n}\n```\n[Playground](https://play.golang.org/p/4C5O3dPayn7)\n\n\n### Function calls\n\n#### Call method without prameters, and without return value\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype A struct{}\n\nfunc (A) Hello() { fmt.Println(\"World\") }\n\nfunc main() {\n\t// ValueOf returns a new Value, which is the reflection interface to a Go value.\n\tv := reflect.ValueOf(A{})\n\tm := v.MethodByName(\"Hello\")\n\tif m.Kind() != reflect.Func {\n\t\treturn\n\t}\n\tm.Call(nil)\n}\n```\n\n#### Call function with list of arguments, and validate return values\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\nfunc Add(a, b int) int { return a + b }\n\nfunc main() {\n\tv := reflect.ValueOf(Add)\n\tif v.Kind() != reflect.Func {\n\t\treturn\n\t}\n\tt := v.Type()\n\targv := make([]reflect.Value, t.NumIn())\n\tfor i := range argv {\n\t\t// validate the type of parameter \"i\".\n\t\tif t.In(i).Kind() != reflect.Int {\n\t\t\treturn\n\t\t}\n\t\targv[i] = reflect.ValueOf(i)\n\t}\n\t// note that, len(result) == t.NumOut()\n\tresult := v.Call(argv)\n\tif len(result) != 1 || result[0].Kind() != reflect.Int {\n\t\treturn\n\t}\n\tfmt.Println(result[0].Int())\n}\n```\n\n#### Call to a function dynamically. similar to the template/text package\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"html/template\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc main() {\n\tfuncs := template.FuncMap{\n\t\t\"trim\":    strings.Trim,\n\t\t\"lower\":   strings.ToLower,\n\t\t\"repeat\":  strings.Repeat,\n\t\t\"replace\": strings.Replace,\n\t}\n\tfmt.Println(eval(`{{ \"hello\" 4 | repeat }}`, funcs))\n\tfmt.Println(eval(`{{ \"Hello-World\" | lower }}`, funcs))\n\tfmt.Println(eval(`{{ \"foobarfoo\" \"foo\" \"bar\" -1 | replace }}`, funcs))\n\tfmt.Println(eval(`{{ \"-^-Hello-^-\" \"-^\" | trim }}`, funcs))\n}\n\n// evaluate an expression. note that this implemetation is assuming that the\n// input is valid, and also very limited. for example, whitespaces are not allowed\n// inside a quoted string.\nfunc eval(s string, funcs template.FuncMap) (string, error) {\n\targs, name := parseArgs(s)\n\tfn, ok := funcs[name]\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"function %s is not defined\", name)\n\t}\n\tv := reflect.ValueOf(fn)\n\tt := v.Type()\n\tif len(args) != t.NumIn() {\n\t\treturn \"\", fmt.Errorf(\"invalid number of arguments. got: %v, want: %v\", len(args), t.NumIn())\n\t}\n\targv := make([]reflect.Value, len(args))\n\t// go over the arguments, validate and build them.\n\t// note that we support only int, and string in this simple example.\n\tfor i := range argv {\n\t\tvar argType reflect.Kind\n\t\t// if the argument \"i\" is string.\n\t\tif strings.HasPrefix(args[i], \"\\\"\") {\n\t\t\targType = reflect.String\n\t\t\targv[i] = reflect.ValueOf(strings.Trim(args[i], \"\\\"\"))\n\t\t} else {\n\t\t\targType = reflect.Int\n\t\t\t// assume that the input is valid.\n\t\t\tnum, _ := strconv.Atoi(args[i])\n\t\t\targv[i] = reflect.ValueOf(num)\n\t\t}\n\t\tif t.In(i).Kind() != argType {\n\t\t\treturn \"\", fmt.Errorf(\"Invalid argument. got: %v, want: %v\", argType, t.In(i).Kind())\n\t\t}\n\t}\n\tresult := v.Call(argv)\n\t// in real-world code, we validate it before executing the function,\n\t// using the v.NumOut() method. similiar to the text/template package.\n\tif len(result) != 1 || result[0].Kind() != reflect.String {\n\t\treturn \"\", fmt.Errorf(\"function %s must return a one string value\", name)\n\t}\n\treturn result[0].String(), nil\n}\n\n// parseArgs is an auxiliary function, that extract the function and its\n// parameter from the given expression.\nfunc parseArgs(s string) ([]string, string) {\n\targs := strings.Split(strings.Trim(s, \"{ }\"), \"|\")\n\treturn strings.Split(strings.Trim(args[0], \" \"), \" \"), strings.Trim(args[len(args)-1], \" \")\n}\n```\n\n#### Call function with variadic parameter\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"reflect\"\n)\n\nfunc Sum(x1, x2 int, xs ...int) int {\n\tsum := x1 + x2\n\tfor _, xi := range xs {\n\t\tsum += xi\n\t}\n\treturn sum\n}\n\nfunc main() {\n\tv := reflect.ValueOf(Sum)\n\tif v.Kind() != reflect.Func {\n\t\treturn\n\t}\n\tt := v.Type()\n\targc := t.NumIn()\n\tif t.IsVariadic() {\n\t\targc += rand.Intn(10)\n\t}\n\targv := make([]reflect.Value, argc)\n\tfor i := range argv {\n\t\targv[i] = reflect.ValueOf(i)\n\t}\n\tresult := v.Call(argv)\n\tfmt.Println(result[0].Int()) // assume that t.NumOut() \u003e 0 tested above.\n}\n```\n\n#### Create function at runtime\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype Add func(int64, int64) int64\n\nfunc main() {\n\tt := reflect.TypeOf(Add(nil))\n\tmul := reflect.MakeFunc(t, func(args []reflect.Value) []reflect.Value {\n\t\ta := args[0].Int()\n\t\tb := args[1].Int()\n\t\treturn []reflect.Value{reflect.ValueOf(a+b)}\n\t})\n\tfn, ok := mul.Interface().(Add)\n\tif !ok {\n\t\treturn\n\t}\n\tfmt.Println(fn(2,3))\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa8m%2Freflect-examples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa8m%2Freflect-examples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa8m%2Freflect-examples/lists"}