β‘οΈ Speed up development? The handy library of most used snippets for Go apps
Vic ShΓ³stak
Posted on May 13, 2023
Introduction
Well, hello, my DEV friends! π
It's been a long time since I had the time, and then the opportunity, to write this blog. But thank you, anyway, for staying with me and asking questions!
I really appreciate it. Love you people! π
Today I'm going to tell you about my personal little project, which I put out to the public quite recently. But it helped me all these years to write Go programs as fast as possible and in full compliance with the DRY (Don't Repeat Yourself) principle.
Intrigued? Then welcome, it will be interesting! π
π Table of contents
- Motivation in library creation
- Basic use of the library
- Regular snippets
- Universal snippets
- Benchmarks
- A win-win cooperation
Motivation in library creation
As you already know from my previous articles, I take an approach to software development that makes the developer's life totally easy.
Why repeat the same snippet, for example, to translate a byte slice to a string, if you can add the most efficient solution to the library once and import it where you need it? Exactly right! It's an unnecessary cognitive load for those who will read your code in the future (and for you as well).
It is for these reasons that The Go Snippet Library (or gosl
for a short) provides snippets collection for working with routine operations in your Go programs with a super user-friendly API and the most efficient performance.
Basic use of the library
Yes, simply add gosl
to your project:
go get github.com/koddr/gosl
Add the needed snippet to your code, like this:
import (
fmt
log
"github.com/koddr/gosl"
)
func main() {
b := []byte("Hello, World!")
s, err := gosl.ToString(b) // convert byte slice to string
if err != nil {
log.Fatal(err)
}
fmt.Println(s)
}
Or like this to have access to snippets as embedded struct:
type App struct {
// ...
utils *gosl.Utility // add regular snippets
genUtils *gosl.GenericUtility[any, comparable] // add generic snippets
}
func (a *App) handleSomething(b []byte) error {
// ...
s, err := a.utils.ToString(b) // convert byte slice to string
if err != nil {
return err
}
// ...
u, err := a.genUtils.Unmarshal(json, model) // unmarshal JSON data to struct
if err != nil {
return err
}
// ...
}
And you are already saving your time and energy. Trust me βοΈ
Regular snippets
The regular snippets of the gosl
package are aimed at solving one single task with the smallest possible allocation of your machine's resources.
Concat
Concatenate strings s
to the one string:
s1 := "this "
s2 := "is "
s3 := "my string"
s := gosl.Concat(s1, s2, s3)
ContainsCaseInsensitive
Report if string substr
is within string s
(case-insensitive by default):
s := "Hello, WORLD!"
substr := "r"
b := gosl.ContainsCaseInsensitive(s, substr)
RandomString
Generates a (really) random string with a given size:
size := 8
s, err := gosl.RandomString(size)
if err != nil {
log.Fatal(err)
}
ToString
Convert byte slice b
to string or error:
b := []byte("Hello, World!")
s, err := gosl.ToString(b)
if err != nil {
log.Fatal(err)
}
ToBytes
Convert string s
to byte slice or error:
s := "Hello, World!"
b, err := gosl.ToBytes(s)
if err != nil {
log.Fatal(err)
}
Universal snippets
The universal (or generic) snippets of the gosl
package are aimed at solving one particular task with the smallest possible allocation of your machine's resources, but can be applied to a huge number of user types.
ContainsInSlice
Report if value v
is within slice s
:
s := []string{"one", "two", "three"}
v := "two"
b := gosl.ContainsInSlice(s, v)
ContainsInMap
Report if key k
is within map m
:
m := map[string]int{"one": 1, "two": 2, "three": 3}
k := "two"
b := gosl.ContainsInMap(m, k)
Marshal
Marshal struct user
to JSON data j
(byte slice) or error:
type user struct {
ID int `json:"id"`
Name string `json:"name"`
}
u := &user{}
j, err := gosl.Marshal(u)
if err != nil {
log.Fatal(err)
}
π‘ This snippet is a 100% compatible drop-in replacement for the standard
encoding/json
library.
Unmarshal
Unmarshal JSON data j
(byte slice) to struct user
or error:
type user struct {
ID int `json:"id"`
Name string `json:"name"`
}
j := []byte(`{"id":1,"name":"Viktor"}`)
m := &user{}
u, err := gosl.Unmarshal(j, m)
if err != nil {
log.Fatal(err)
}
π‘ This snippet (also) is a 100% compatible drop-in replacement for the standard
encoding/json
library.
Benchmarks
My results for all snippets in the library (the test stand is Apple MacBook Air M1, 16Β GB RAM, macOS 13.3.1):
BenchmarkConcat_String2-8 58663996 20.06 ns/op 32 B/op 1 allocs/op
BenchmarkConcat_String8-8 26829356 44.16 ns/op 128 B/op 1 allocs/op
BenchmarkConcat_String32-8 9321133 127.8 ns/op 448 B/op 1 allocs/op
BenchmarkToString_HelloWorld-8 100000000 10.56 ns/op 16 B/op 1 allocs/op
BenchmarkToBytes_HelloWorld-8 1000000000 0.6288 ns/op 0 B/op 0 allocs/op
BenchmarkRandomString_Size1-8 3488678 344.6 ns/op 6 B/op 3 allocs/op
BenchmarkRandomString_Size8-8 3394548 353.3 ns/op 24 B/op 3 allocs/op
BenchmarkRandomString_Size64-8 2313856 517.9 ns/op 160 B/op 3 allocs/op
BenchmarkRandomString_Size512-8 1423572 838.9 ns/op 1280 B/op 3 allocs/op
BenchmarkRandomString_Size4096-8 185337 6350 ns/op 10240 B/op 3 allocs/op
BenchmarkMarshal_StructField_4-8 8584442 139.9 ns/op 48 B/op 3 allocs/op
BenchmarkMarshal_StructField_16-8 2838062 420.8 ns/op 192 B/op 3 allocs/op
BenchmarkUnmarshal_StructField_4-8 6960462 169.3 ns/op 32 B/op 3 allocs/op
BenchmarkUnmarshal_StructField_16-8 764182 1553 ns/op 864 B/op 45 allocs/op
BenchmarkContainsCaseInsensitive_HelloWorld-8 24856041 48.46 ns/op 16 B/op 1 allocs/op
BenchmarkContainsCaseInsensitive_LoremIpsum-8 1797150 695.9 ns/op 448 B/op 1 allocs/op
BenchmarkContainsInSlice-8 122999034 9.758 ns/op 0 B/op 0 allocs/op
BenchmarkContainsInMap-8 19123504 62.61 ns/op 0 B/op 0 allocs/op
A win-win cooperation
I invite every user of Dev.to (and my lowly blog, certainly) to participate in this project! Let's work together to create the largest and most useful library of snippets for Go programs on the web today.
- Ask questions and submit your features to the Issues section.
- Send your snippets or improvements to the current to the Pull requests section.
Your PRs & issues are welcome! Thanks π
Photos and videos by
- Marc Sendra Martorell https://unsplash.com/photos/-Vqn2WrfxTQ
- Vic ShΓ³stak https://github.com/koddr
P.S.
If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! π»
βοΈ You can support me on Boosty, both on a permanent and on a one-time basis. All proceeds from this way will go to support my OSS projects and will energize me to create new products and articles for the community.
And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!
My main projects that need your help (and stars) π
- π₯ gowebly: A next-generation CLI tool that makes it easy to create amazing web applications with Go on the backend, using htmx, hyperscript or Alpine.js and the most popular CSS frameworks on the frontend.
- β¨ create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
Posted on May 13, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.