Generics based GoLang library to allow type to type casting. No extra dependencies.
🚧 The module under construction! 🚧
go get -u github.com/the-go-tool/cast
As long as the module uses generics Go 1.18 or above must be installed. Learn more about generics if you haven't.
Key feature that we have only several methods with type inference to make casts. Let's look at the example:
str := "42"
i := cast.To[int](str)
// Result: i is int(42) now
It's possible to use any of primitive types like all types of int, uint, bool, string and their derivatives also. Another example with custom type based on primitive value:
package main
import (
"fmt"
"github.com/the-go-tool/cast"
)
type Custom string
func main() {
custom := cast.To[Custom](256)
fmt.Println(custom) // string "256"
}
We learned about most common function cast.To. But what if our program can't cast one type to other by some reason? For example, we're trying to cast string "non-int" to int. In this case we'll get int(0) and won't know about error via cast.To.
Another one used function is cast.WithError which returns casted value and error if it happens:
i, err := cast.WithError[int]("non-int")
fmt.Println(i) // int(0) so it's default value for int
fmt.Println(err) // "strconv.ParseInt: parsing "non-int": invalid syntax"
Also we can check casting possibility like so:
if cast.Possible[int]("non-int") {
fmt.Println("casting possible")
} else {
fmt.Println("mission impossible") // will print
}
And very rare case when we need to panic in case of impossible casting:
i := cast.MustTo[int]("non-int") // panics
This module has flexible API. So, you can register your own type for casting:
type Custom int
func init() {
MustRegister(func(in Custom) (out int, err error) {
return int(in), nil
})
}
Now we can use Custom -> int casting like so:
func main() {
fmt.Println(cast.To[int](Custom(5))) // int 5
}
It's going to be tedious to write casting function for each types. But this module provides casting proxies. Look:
MustRegisterProxy[Custom, string, int]() // Input, Output, Proxy
fmt.Println(cast.To[string](Custom(5))) // string 5
Because we already registered Custom -> int and we have default int -> string casters just register chain Custom -> int -> string.
Casting between related types but different sizes.
To[int](int32(5)) //> int(5)
To[uint8](uint16(500)) //> uint8(244), so 500-256=244
To[float32](float64(6.9)) //> float32(6.9)
To[byte](uint(5)) //> uint8(5), so byte is alias for uint8
To[rune](int(50)) //> int32(50), so rune is alias for int32
Type X | X from/to X |
---|---|
ints | ✅ |
uints | ✅ |
floats | ✅ |
complexes | ✅ |
Casting between number types (with possible different sizes).
To[int](56.6) //> int(56), only integer part
To[float32](56) //> float32(56)
To[uint8](int8(-40)) //> uint8(216), so 256-40=216
To[uint64](int8(-1)) //> uint64(MAX_VALUE)
To[float32](complex(5, -1)) //> float32(5)
Type N1 | Type N2 | N1 from/to N2 |
---|---|---|
ints | uints | ✅ |
ints | floats | ✅ |
ints | complexes | ✅ |
uints | floats | ✅ |
uints | complexes | ✅ |
floats | complexes | ✅ |
Casting between string and anything basic type. Usually, it's close to
strconv
standard behavior except boolean.Casting from string to boolean extended and accepts any of
1
,+
,t
,true
,y
,yes
astrue
and any of0
,-
,f
,false
,n
,no
asfalse
. It's space trimmed and case insensitive. Any other string values will produce an error.
To[bool]("y") //> true
To[bool](" 1 ") //> true
To[bool](" n ") //> false
To[bool](" dsa ") //> false, and error for WithError
To[string](true) //> "true"
To[string](complex(-1, -2)) //> "(-1-2i)"
To[int]("-5") //> int(-5)
To[int]("+5") //> int(5)
To[int]("5.6") //> int(0), and error for WithError
To[float32]("5.6") //> float32(5.6)
Type S | Type A | S from/to A |
---|---|---|
string | ints | ✅ |
string | uints | ✅ |
string | floats | ✅ |
string | complexes | ✅ |
string | bool | ✅ |
Casting between boolean and number types.
true
alway will be1
if cast to number or1+0i
for complexes. Number willtrue
if value isn't equal0
. For complexes only real part is matter.
To[int](true) //> int(1)
To[int](false) //> int(0)
To[bool](int(0)) //> false
To[bool](int(-1)) //> true
To[bool](uint(1)) //> true
To[bool](complex(0, 5)) //> false, so only real part matter
To[bool](complex(5, 0)) //> true
Type B | Cast N | B from/to N |
---|---|---|
bool | ints | ✅ |
bool | uints | ✅ |
bool | floats | ✅ |
bool | complexes | ✅ |
Please, star this repository if you find it helpful ⭐
Also, make an issue
if you found a bug or would like for some improvements.
If this module doesn't fit here is links to similar projects: