├── go.mod ├── .github └── FUNDING.yml ├── of.go ├── example_test.go ├── LICENSE └── README.md /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/carlmjohnson/new 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: carlmjohnson 4 | -------------------------------------------------------------------------------- /of.go: -------------------------------------------------------------------------------- 1 | // Package new allocates a new variable of a given value and returns a pointer to it. 2 | package new 3 | 4 | // Of allocates a new variable of a given value and returns a pointer to it. 5 | func Of[T any](value T) *T { 6 | return &value 7 | } 8 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | package new_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/carlmjohnson/new" 7 | ) 8 | 9 | func ExampleOf() { 10 | strptr1 := new.Of("meaning of life") 11 | strptr2 := new.Of("meaning of life") 12 | fmt.Println(strptr1 != strptr2) 13 | fmt.Println(*strptr1 == *strptr2) 14 | 15 | intp1 := new.Of(42) 16 | intp2 := new.Of(42) 17 | fmt.Println(intp1 != intp2) 18 | fmt.Println(*intp1 == *intp2) 19 | 20 | type MyFloat float64 21 | fp := new.Of[MyFloat](42) 22 | fmt.Println(fp != nil) 23 | fmt.Println(*fp == 42) 24 | 25 | // Output: 26 | // true 27 | // true 28 | // true 29 | // true 30 | // true 31 | // true 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Carl Johnson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # new.Of 2 | A helper function to create a pointer to a new variable of a particular value in Go 1.18+. 3 | 4 | ``` 5 | strptr1 := new.Of("meaning of life") 6 | strptr2 := new.Of("meaning of life") 7 | strptr1 != strptr2 // true 8 | *strptr1 == *strptr2 // true 9 | 10 | intp1 := new.Of(42) 11 | intp2 := new.Of(42) 12 | intp1 != intp2 // true 13 | *intp1 == *intp2 // true 14 | 15 | type MyFloat float64 16 | fp := new.Of[MyFloat](42) 17 | fp != nil // true 18 | *fp == 42 // true 19 | ``` 20 | 21 | ## Installation 22 | 23 | As of November 2021, Go 1.18 is not released, but you can install Go tip with 24 | 25 | ``` 26 | $ go install golang.org/dl/gotip@latest 27 | $ gotip download 28 | $ gotip init me/myproject 29 | $ gotip get github.com/carlmjohnson/new 30 | ``` 31 | 32 | ## FAQs 33 | 34 | ### [I love and hate this at the same time...](https://reddit.com/r/golang/comments/r064xk/_/hlr2bdi/?context=1) 35 | 36 | I mean, honestly, this isn't even my worst idea for generics yet. 37 | 38 | ### What problem does this solve exactly? 39 | 40 | In Go, you cannot return a pointer to an expression, although you can return a pointer to a struct literal. As a result, `return &struct{ 42 }` is legal, but `return &42` is not. To work around this, many popular packages include pointer helpers, such as [aws.String](https://pkg.go.dev/github.com/aws/aws-sdk-go/aws#String) and [github.Int64](https://pkg.go.dev/github.com/google/go-github/v39/github#Int64). Thanks to generics, now one function can solve this problem once and for all. 41 | 42 | ### How can you name a package `new`? 43 | 44 | `new` is a built-in function, not a keyword, so it is legal to shadow the name. If this is a problem for your code because you are still using the built-in `new` function in legacy code, you can use an import alias for this package. 45 | 46 | ### What does test coverage look like? 47 | 48 | 100%, baby. 49 | 50 | ### Should I use this package? 51 | 52 | Ideally, `newof` will become [a built-in function in a future version of Go](https://github.com/golang/go/issues/45624#issuecomment-927391928). Until then, [this is fine](http://gunshowcomic.com/648). 53 | 54 | [![fine](https://user-images.githubusercontent.com/222245/142966985-627d6095-313f-475f-ba98-fa37ef892cbe.png)](https://github.com/carlmjohnson/shitpic/) 55 | --------------------------------------------------------------------------------