{"id":20476831,"url":"https://github.com/oleiade/reflections","last_synced_at":"2025-10-23T19:41:52.953Z","repository":{"id":9989036,"uuid":"12019383","full_name":"oleiade/reflections","owner":"oleiade","description":"High level abstractions over the Go reflect library","archived":false,"fork":false,"pushed_at":"2024-08-24T17:12:08.000Z","size":69,"stargazers_count":528,"open_issues_count":5,"forks_count":51,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-05-09T05:04:06.324Z","etag":null,"topics":["go","golang","reflect","reflection","runtime","types"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/oleiade/reflections","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oleiade.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-08-10T10:48:39.000Z","updated_at":"2025-04-06T18:38:49.000Z","dependencies_parsed_at":"2024-11-15T15:23:53.601Z","dependency_job_id":"9d729e5e-1538-429a-b4f5-df08b63d3c0b","html_url":"https://github.com/oleiade/reflections","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleiade%2Freflections","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleiade%2Freflections/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleiade%2Freflections/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleiade%2Freflections/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oleiade","download_url":"https://codeload.github.com/oleiade/reflections/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243360,"owners_count":22038046,"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":["go","golang","reflect","reflection","runtime","types"],"created_at":"2024-11-15T15:23:29.483Z","updated_at":"2025-10-23T19:41:47.898Z","avatar_url":"https://github.com/oleiade.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Reflections\n\n[![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://choosealicense.com/licenses/mit/)\n[![Build Status](https://github.com/oleiade/reflections/actions/workflows/go.yml/badge.svg)](https://github.com/oleiade/reflections/actions/workflows/go.yml)\n[![Go Documentation](https://pkg.go.dev/badge/github.com/oleiade/reflections)](https://pkg.go.dev/github.com/oleiade/reflections)\n[![Go Report Card](https://goreportcard.com/badge/github.com/oleiade/reflections)](https://goreportcard.com/report/github.com/oleiade/reflections)\n![Go Version](https://img.shields.io/github/go-mod/go-version/oleiade/reflections)\n\nThe `reflections` library provides high-level abstractions on top of the go language standard `reflect` library.\n\nIn practice, the `reflect` library's API proves somewhat low-level and un-intuitive. Using it can turn out pretty complex, daunting, and scary, especially when doing simple things like accessing a structure field value, a field tag, etc.\n\nThe `reflections` package aims to make developers' life easier when it comes to introspect struct values at runtime. Its API takes inspiration in the python language's `getattr,` `setattr,` and `hasattr` set of methods and provides simplified access to structure fields and tags.\n\n- [Reflections](#reflections)\n  - [Documentation](#documentation)\n  - [Usage](#usage)\n    - [`GetField`](#getfield)\n    - [`GetFieldKind`](#getfieldkind)\n    - [`GetFieldType`](#getfieldtype)\n    - [`GetFieldTag`](#getfieldtag)\n    - [`HasField`](#hasfield)\n    - [`Fields`](#fields)\n    - [`Items`](#items)\n    - [`Tags`](#tags)\n    - [`GetFieldNameByTagValue`](#getfieldnamebytagvalue)\n  - [Important notes](#important-notes)\n  - [Contribute](#contribute)\n\n## Documentation\n\nHead to the [documentation](https://pkg.go.dev/github.com/oleiade/reflections) to get more details on the library's API.\n\n## Usage\n\n### `GetField`\n\n`GetField` returns the content of a structure field. For example, it proves beneficial when you want to iterate over struct-specific field values. You can provide `GetField` a structure or a pointer to a struct as the first argument.\n\n```go\ns := MyStruct {\n    FirstField: \"first value\",\n    SecondField: 2,\n    ThirdField: \"third value\",\n}\n\nfieldsToExtract := []string{\"FirstField\", \"ThirdField\"}\n\nfor _, fieldName := range fieldsToExtract {\n    value, err := reflections.GetField(s, fieldName)\n    DoWhatEverWithThatValue(value)\n}\n```\n\n### `GetFieldKind`\n\n`GetFieldKind` returns the [`reflect.Kind`](http://golang.org/src/pkg/reflect/type.go?s=6916:6930#L189) of a structure field. You can use it to operate type assertion over a structure field at runtime. You can provide `GetFieldKind` a structure or a pointer to structure as the first argument.\n\n```go\ns := MyStruct{\n    FirstField: \"first value\",\n    SecondField: 2,\n    ThirdField: \"third value\",\n}\n\nvar firstFieldKind reflect.String\nvar secondFieldKind reflect.Int\nvar err error\n\nfirstFieldKind, err = GetFieldKind(s, \"FirstField\")\nif err != nil {\n    log.Fatal(err)\n}\n\nsecondFieldKind, err = GetFieldKind(s, \"SecondField\")\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n### `GetFieldType`\n\n`GetFieldType` returns the string literal of a structure field type. You can use it to operate type assertion over a structure field at runtime. You can provide `GetFieldType` a structure or a pointer to structure as the first argument.\n\n```go\ns := MyStruct{\n    FirstField: \"first value\",\n    SecondField: 2,\n    ThirdField: \"third value\",\n}\n\nvar firstFieldKind string\nvar secondFieldKind string\nvar err error\n\nfirstFieldKind, err = GetFieldType(s, \"FirstField\")\nif err != nil {\n    log.Fatal(err)\n}\n\nsecondFieldKind, err = GetFieldType(s, \"SecondField\")\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n### `GetFieldTag`\n\n`GetFieldTag` extracts a specific structure field tag. You can provide `GetFieldTag` a structure or a pointer to structure as the first argument.\n\n```go\ns := MyStruct{}\n\ntag, err := reflections.GetFieldTag(s, \"FirstField\", \"matched\")\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Println(tag)\n\ntag, err = reflections.GetFieldTag(s, \"ThirdField\", \"unmatched\")\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Println(tag)\n```\n\n### `HasField`\n\n`HasField` asserts a field exists through the structure. You can provide `HasField` a struct or a pointer to a struct as the first argument.\n\n```go\ns := MyStruct {\n    FirstField: \"first value\",\n    SecondField: 2,\n    ThirdField: \"third value\",\n}\n\n// has == true\nhas, _ := reflections.HasField(s, \"FirstField\")\n\n// has == false\nhas, _ := reflections.HasField(s, \"FourthField\")\n```\n\n### `Fields`\n\n`Fields` returns the list of structure field names so that you can access or update them later. You can provide `Fields` with a struct or a pointer to a struct as the first argument.\n\n```go\ns := MyStruct {\n    FirstField: \"first value\",\n    SecondField: 2,\n    ThirdField: \"third value\",\n}\n\nvar fields []string\n\n// Fields will list every structure exportable fields.\n// Here, it's content would be equal to:\n// []string{\"FirstField\", \"SecondField\", \"ThirdField\"}\nfields, _ = reflections.Fields(s)\n```\n\n### `Items`\n\n`Items` returns the structure's field name to the values map. You can provide `Items` with a struct or a pointer to structure as the first argument.\n\n```go\ns := MyStruct {\n    FirstField: \"first value\",\n    SecondField: 2,\n    ThirdField: \"third value\",\n}\n\nvar structItems map[string]interface{}\n\n// Items will return a field name to\n// field value map\nstructItems, _ = reflections.Items(s)\n```\n\n### `Tags`\n\n`Tags` returns the structure's fields tag with the provided key. You can provide `Tags` with a struct or a pointer to a struct as the first argument.\n\n```go\ns := MyStruct {\n    FirstField: \"first value\",      `matched:\"first tag\"`\n    SecondField: 2,                 `matched:\"second tag\"`\n    ThirdField: \"third value\",      `unmatched:\"third tag\"`\n}\n\nvar structTags map[string]string\n\n// Tags will return a field name to tag content\n// map. N.B that only field with the tag name\n// you've provided will be matched.\n// Here structTags will contain:\n// {\n// \"FirstField\": \"first tag\",\n// \"SecondField\": \"second tag\",\n// }\nstructTags, _ = reflections.Tags(s, \"matched\")\n```\n\n### `SetField`\n\n`SetField` updates a structure's field value with the one provided. Note that you can't set un-exported fields and that the field and value types must match.\n\n```go\ns := MyStruct {\n    FirstField: \"first value\",\n    SecondField: 2,\n    ThirdField: \"third value\",\n}\n\n//To be able to set the structure's values,\n// it must be passed as a pointer.\n_ := reflections.SetField(\u0026s, \"FirstField\", \"new value\")\n\n// If you try to set a field's value using the wrong type,\n// an error will be returned\nerr := reflection.SetField(\u0026s, \"FirstField\", 123) // err != nil\n```\n\n### `GetFieldNameByTagValue`\n\n`GetFieldNameByTagValue` looks up a field with a matching `{tagKey}:\"{tagValue}\"` tag in the provided `obj` item.\nIf `obj` is not a `struct`, nor a `pointer`, or it does not have a field tagged with the `tagKey`, and the matching `tagValue`, this function returns an error. \n\n```go\ns := MyStruct {\n    FirstField: \"first value\",      `matched:\"first tag\"`\n    SecondField: 2,                 `matched:\"second tag\"`\n    ThirdField: \"third value\",      `unmatched:\"third tag\"`\n}\n\n// Getting field name from external source as json would be a headache to convert it manually, \n// so we get it directly from struct tag\n// returns fieldName = \"FirstField\"\nfieldName, _ = reflections.GetFieldNameByTagValue(s, \"matched\", \"first tag\");\n\n// later we can do GetField(s, fieldName)\n```\n\n\n## Important notes\n\n- **Un-exported fields** can't be accessed nor set using the `reflections` library. The Go lang standard `reflect` library intentionally prohibits un-exported fields values access or modifications.\n\n## Contribute\n\n- Check for open issues or open a new issue to start a discussion around a feature idea or a bug.\n- Fork [the repository](http://github.com/oleiade/reflections) on GitHub to start making your changes to the **master** branch, or branch off of it.\n- Write tests showing that the bug was fixed or the feature works as expected.\n- Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to [`AUTHORS`](https://github.com/oleiade/reflections/blob/master/AUTHORS.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foleiade%2Freflections","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foleiade%2Freflections","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foleiade%2Freflections/lists"}