{"id":13564196,"url":"https://github.com/moznion/go-optional","last_synced_at":"2025-04-04T06:06:34.129Z","repository":{"id":37980111,"uuid":"429126675","full_name":"moznion/go-optional","owner":"moznion","description":"A library that provides Go Generics friendly \"optional\" features.","archived":false,"fork":false,"pushed_at":"2024-10-04T16:06:54.000Z","size":96,"stargazers_count":155,"open_issues_count":3,"forks_count":11,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-10-17T23:55:10.253Z","etag":null,"topics":["generics","go","golang","optional","optional-typing"],"latest_commit_sha":null,"homepage":"","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/moznion.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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-17T16:47:46.000Z","updated_at":"2024-10-17T23:00:10.000Z","dependencies_parsed_at":"2023-11-13T10:25:10.260Z","dependency_job_id":"929229cb-5b98-4840-be82-3ff416fee0f1","html_url":"https://github.com/moznion/go-optional","commit_stats":{"total_commits":55,"total_committers":6,"mean_commits":9.166666666666666,"dds":"0.32727272727272727","last_synced_commit":"7f202adcea8a86e4878d30be259bbe6a301fc285"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fgo-optional","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fgo-optional/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fgo-optional/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moznion%2Fgo-optional/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moznion","download_url":"https://codeload.github.com/moznion/go-optional/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247128743,"owners_count":20888235,"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":["generics","go","golang","optional","optional-typing"],"created_at":"2024-08-01T13:01:27.840Z","updated_at":"2025-04-04T06:06:34.112Z","avatar_url":"https://github.com/moznion.png","language":"Go","readme":"# go-optional [![.github/workflows/check.yml](https://github.com/moznion/go-optional/actions/workflows/check.yml/badge.svg)](https://github.com/moznion/go-optional/actions/workflows/check.yml) [![codecov](https://codecov.io/gh/moznion/go-optional/branch/main/graph/badge.svg?token=0HCVy6COy4)](https://codecov.io/gh/moznion/go-optional) [![GoDoc](https://godoc.org/github.com/moznion/go-optional?status.svg)](https://godoc.org/github.com/moznion/go-optional)\n\nA library that provides [Go Generics](https://go.dev/blog/generics-proposal) friendly \"optional\" features.\n\n## Synopsis\n\n```go\nsome := optional.Some[int](123)\nfmt.Printf(\"%v\\n\", some.IsSome()) // =\u003e true\nfmt.Printf(\"%v\\n\", some.IsNone()) // =\u003e false\n\nv, err := some.Take()\nfmt.Printf(\"err is nil: %v\\n\", err == nil) // =\u003e err is nil: true\nfmt.Printf(\"%d\\n\", v) // =\u003e 123\n\nmapped := optional.Map(some, func (v int) int {\n    return v * 2\n})\nfmt.Printf(\"%v\\n\", mapped.IsSome()) // =\u003e true\n\nmappedValue, _ := some.Take()\nfmt.Printf(\"%d\\n\", mappedValue) // =\u003e 246\n```\n\n```go\nnone := optional.None[int]()\nfmt.Printf(\"%v\\n\", none.IsSome()) // =\u003e false\nfmt.Printf(\"%v\\n\", none.IsNone()) // =\u003e true\n\n_, err := none.Take()\nfmt.Printf(\"err is nil: %v\\n\", err == nil) // =\u003e err is nil: false\n// the error must be `ErrNoneValueTaken`\n\nmapped := optional.Map(none, func (v int) int {\n    return v * 2\n})\nfmt.Printf(\"%v\\n\", mapped.IsNone()) // =\u003e true\n```\n\nand more detailed examples are here: [./examples_test.go](./examples_test.go).\n\n## Docs\n\n[![GoDoc](https://godoc.org/github.com/moznion/go-optional?status.svg)](https://godoc.org/github.com/moznion/go-optional)\n\n### Supported Operations\n\n#### Value Factory Methods\n\n- [Some[T]\\() Option[T]](https://pkg.go.dev/github.com/moznion/go-optional#Some)\n- [None[T]\\() Option[T]](https://pkg.go.dev/github.com/moznion/go-optional#None)\n- [FromNillable[T]\\() Option[T]](https://pkg.go.dev/github.com/moznion/go-optional#FromNillable)\n- [PtrFromNillable[T]\\() Option[T]](https://pkg.go.dev/github.com/moznion/go-optional#PtrFromNillable)\n\n#### Option value handler methods\n\n- [Option[T]#IsNone() bool](https://pkg.go.dev/github.com/moznion/go-optional#Option.IsNone)\n- [Option[T]#IsSome() bool](https://pkg.go.dev/github.com/moznion/go-optional#Option.IsSome)\n- [Option[T]#Unwrap() T](https://pkg.go.dev/github.com/moznion/go-optional#Option.Unwrap)\n- [Option[T]#UnwrapAsPtr() \\*T](https://pkg.go.dev/github.com/moznion/go-optional#Option.UnwrapAsPtr)\n- [Option[T]#Take() (T, error)](https://pkg.go.dev/github.com/moznion/go-optional#Option.Take)\n- [Option[T]#TakeOr(fallbackValue T) T](https://pkg.go.dev/github.com/moznion/go-optional#Option.TakeOr)\n- [Option[T]#TakeOrElse(fallbackFunc func() T) T](https://pkg.go.dev/github.com/moznion/go-optional#Option.TakeOrElse)\n- [Option[T]#Or(fallbackOptionValue Option[T]) Option[T]](https://pkg.go.dev/github.com/moznion/go-optional#Option.Or)\n- [Option[T]#OrElse(fallbackOptionFunc func() Option[T]) Option[T]](https://pkg.go.dev/github.com/moznion/go-optional#Option.OrElse)\n- [Option[T]#Filter(predicate func(v T) bool) Option[T]](https://pkg.go.dev/github.com/moznion/go-optional#Option.Filter)\n- [Option[T]#IfSome(f func(v T))](https://pkg.go.dev/github.com/moznion/go-optional#Option.IfSome)\n- [Option[T]#IfSomeWithError(f func(v T) error) error](https://pkg.go.dev/github.com/moznion/go-optional#Option.IfSomeWithError)\n- [Option[T]#IfNone(f func())](https://pkg.go.dev/github.com/moznion/go-optional#Option.IfNone)\n- [Option[T]#IfNoneWithError(f func() error) error](https://pkg.go.dev/github.com/moznion/go-optional#Option.IfNoneWithError)\n- [Option.Map[T, U any](option Option[T], mapper func(v T) U) Option[U]](https://pkg.go.dev/github.com/moznion/go-optional#Map)\n- [Option.MapOr[T, U any](option Option[T], fallbackValue U, mapper func(v T) U) U](https://pkg.go.dev/github.com/moznion/go-optional#MapOr)\n- [Option.MapWithError[T, U any](option Option[T], mapper func(v T) (U, error)) (Option[U], error)](https://pkg.go.dev/github.com/moznion/go-optional#MapWithError)\n- [Option.MapOrWithError[T, U any](option Option[T], fallbackValue U, mapper func(v T) (U, error)) (U, error)](https://pkg.go.dev/github.com/moznion/go-optional#MapOrWithError)\n- [Option.FlatMap[T, U any](option Option[T], mapper func(v T) Option[U]) Option[U]](https://pkg.go.dev/github.com/moznion/go-optional#FlatMap)\n- [Option.FlatMapOr[T, U any](option Option[T], fallbackValue U, mapper func(v T) Option[U]) U](https://pkg.go.dev/github.com/moznion/go-optional#FlatMapOr)\n- [Option.FlatMapWithError[T, U any](option Option[T], mapper func(v T) (Option[U], error)) (Option[U], error)](https://pkg.go.dev/github.com/moznion/go-optional#FlatMapWithError)\n- [Option.FlatMapOrWithError[T, U any](option Option[T], fallbackValue U, mapper func(v T) (Option[U], error)) (U, error)](https://pkg.go.dev/github.com/moznion/go-optional#FlatMapOrWithError)\n- [Option.Zip[T, U any](opt1 Option[T], opt2 Option[U]) Option[Pair[T, U]]](https://pkg.go.dev/github.com/moznion/go-optional#Zip)\n- [Option.ZipWith[T, U, V any](opt1 Option[T], opt2 Option[U], zipper func(opt1 T, opt2 U) V) Option[V]](https://pkg.go.dev/github.com/moznion/go-optional#ZipWith)\n- [Option.Unzip[T, U any](zipped Option[Pair[T, U]]) (Option[T], Option[U])](https://pkg.go.dev/github.com/moznion/go-optional#Unzip)\n- [Option.UnzipWith[T, U, V any](zipped Option[V], unzipper func(zipped V) (T, U)) (Option[T], Option[U])](https://pkg.go.dev/github.com/moznion/go-optional#UnzipWith)\n\n### nil == None[T]\n\nThis library deals with `nil` as same as `None[T]`. So it works with like the following example:\n\n```go\nvar nilValue Option[int] = nil\nfmt.Printf(\"%v\\n\", nilValue.IsNone()) // =\u003e true\nfmt.Printf(\"%v\\n\", nilValue.IsSome()) // =\u003e false\n```\n\n### JSON marshal/unmarshal support\n\nThis `Option[T]` type supports JSON marshal and unmarshal.\n\nIf the value wanted to marshal is `Some[T]` then it marshals that value into the JSON bytes simply, and in unmarshaling, if the given JSON string/bytes has the actual value on corresponded property, it unmarshals that value into `Some[T]` value.\n\nexample:\n\n```go\ntype JSONStruct struct {\n\tVal Option[int] `json:\"val\"`\n}\n\nsome := Some[int](123)\njsonStruct := \u0026JSONStruct{Val: some}\n\nmarshal, err := json.Marshal(jsonStruct)\nif err != nil {\n\treturn err\n}\nfmt.Printf(\"%s\\n\", marshal) // =\u003e {\"val\":123}\n\nvar unmarshalJSONStruct JSONStruct\nerr = json.Unmarshal(marshal, \u0026unmarshalJSONStruct)\nif err != nil {\n\treturn err\n}\n// unmarshalJSONStruct.Val == Some[int](123)\n```\n\nElsewise, when the value is `None[T]`, the marshaller serializes that value as `null`. And if the unmarshaller gets the JSON `null` value on a property corresponding to the `Optional[T]` value, or the value of a property is missing, that deserializes that value as `None[T]`.\n\nexample:\n\n```go\ntype JSONStruct struct {\n\tVal Option[int] `json:\"val\"`\n}\n\nnone := None[int]()\njsonStruct := \u0026JSONStruct{Val: none}\n\nmarshal, err := json.Marshal(jsonStruct)\nif err != nil {\n\treturn err\n}\nfmt.Printf(\"%s\\n\", marshal) // =\u003e {\"val\":null}\n\nvar unmarshalJSONStruct JSONStruct\nerr = json.Unmarshal(marshal, \u0026unmarshalJSONStruct)\nif err != nil {\n\treturn err\n}\n// unmarshalJSONStruct.Val == None[int]()\n```\n\nAnd this also supports `omitempty` option for JSON unmarshaling. If the value of the property is `None[T]` and that property has `omitempty` option, it omits that property.\n\nref:\n\n\u003e The \"omitempty\" option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string.\n\u003e https://pkg.go.dev/encoding/json#Marshal\n\nexample:\n\n```go\ntype JSONStruct struct {\n\tOmitemptyVal Option[string] `json:\"omitemptyVal,omitempty\"` // this should be omitted\n}\n\njsonStruct := \u0026JSONStruct{OmitemptyVal: None[string]()}\nmarshal, err := json.Marshal(jsonStruct)\nif err != nil {\n\treturn err\n}\nfmt.Printf(\"%s\\n\", marshal) // =\u003e {}\n```\n\n### SQL Driver Support\n\n`Option[T]` satisfies [sql/driver.Valuer](https://pkg.go.dev/database/sql/driver#Valuer) and [sql.Scanner](https://pkg.go.dev/database/sql#Scanner), so this type can be used by SQL interface on Golang.\n\nexample of the primitive usage:\n\n```go\nsqlStmt := \"CREATE TABLE tbl (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(32));\"\ndb.Exec(sqlStmt)\n\ntx, _ := db.Begin()\nfunc() {\n    stmt, _ := tx.Prepare(\"INSERT INTO tbl(id, name) values(?, ?)\")\n    defer stmt.Close()\n    stmt.Exec(1, \"foo\")\n}()\nfunc() {\n    stmt, _ := tx.Prepare(\"INSERT INTO tbl(id) values(?)\")\n    defer stmt.Close()\n    stmt.Exec(2) // name is NULL\n}()\ntx.Commit()\n\nvar maybeName Option[string]\n\nrow := db.QueryRow(\"SELECT name FROM tbl WHERE id = 1\")\nrow.Scan(\u0026maybeName)\nfmt.Println(maybeName) // Some[foo]\n\nrow := db.QueryRow(\"SELECT name FROM tbl WHERE id = 2\")\nrow.Scan(\u0026maybeName)\nfmt.Println(maybeName) // None[]\n```\n\n## Known Issues\n\nThe runtime raises a compile error like \"methods cannot have type parameters\", so `Map()`, `MapOr()`, `MapWithError()`, `MapOrWithError()`, `Zip()`, `ZipWith()`, `Unzip()` and `UnzipWith()` have been providing as functions. Basically, it would be better to provide them as the methods, but currently, it compromises with the limitation.\n\n## Author\n\nmoznion (\u003cmoznion@mail.moznion.net\u003e)\n\n","funding_links":[],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoznion%2Fgo-optional","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoznion%2Fgo-optional","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoznion%2Fgo-optional/lists"}