mcuadros / go-defaults Goto Github PK
View Code? Open in Web Editor NEWGo structures with default values using tags
License: MIT License
Go structures with default values using tags
License: MIT License
Example:
type Widget struct {
B []bytes
}
defaults.SetDefaults(&Widget{})
The B
field starts out nil, but will be set to an empty byte slice, even though that field has no "default" tag.
Looking at the code, I'm thinking either setDefaultValues
should check for the presence of the tag, and skip the field if not present, or setDefaultValue
should check the presence of the tag (after the zero value check).
Alternatively, if this was the intended behavior, then perhaps add a default:"-" option to explicitly skip the field? Or a flag in the Filler struct to toggle the behavior? I'd be happy to do a PR.
In v1.1.0, setting default: "1000000000" for time.Duration was equivalent to "1s".
but, In v1.2.0, setting default: "1000000000" for time.Duration is equivalent to "0".
I have made the fixes in this Pull Request. #18
Please check it out as it is a necessary fix for the project I am using.
I'd love it if this library also handled type pointers, so something like this:
type test struct {
Name *string `default:"test"`
}
now obviously a string pointer isn't the most useful thing in the world, but handling it generically should allow us to specify nested struct pointers with their own defaults, and then this library would correctly initialize the whole data tree. I've written a little bit of wrapper code to do this myself (which actually doesn't even handle the string pointer case), but I'd love it if this was something the library just did itself:
setDefaults(reflect.ValueOf(test))
[...]
func setDefaults(v reflect.Value) {
if v.Kind() != reflect.Ptr { return }
if v.IsNil() {
if v.CanSet() {
v.Set(reflect.New(v.Type().Elem()))
} else {
return
}
}
if v.Elem().Kind() != reflect.Struct { return }
defaults.SetDefaults(v.Interface())
v = v.Elem()
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
if field.Type().Kind() == reflect.Ptr {
setDefaults(field)
}
}
}
How can I get the default value of one field derived from other fields of same struct, For example:
type User struct {
Name string
FirstName string
LastName string
}
Here the default value of Name will be derived from FirstName and LastName i.e., Name = concat(FirstName,' ',LastName).
Is there any way to achieve this? @mcuadros Let me know
For fields of type time.Duration
the documentation suggests that a default of "1m" should be parsed into the appropriate duration (i.e. 1 * time.Minute
).
This does not seem to be working.
Defaults are only correctly applied when using numbers only (which are then interpreted as nanoseconds:
import (
"fmt"
"time"
"github.com/mcuadros/go-defaults"
)
type Foo struct {
ConnectionTimeout time.Duration `default:"2000000000"`
}
func main() {
c := &Foo{}
defaults.SetDefaults(c)
fmt.Printf("Foo: %+v", c)
}
Output:
Foo: &{ConnectionTimeout:2s}
However:
import (
"fmt"
"time"
"github.com/mcuadros/go-defaults"
)
type Foo struct {
ConnectionTimeout time.Duration `default:"20s"`
}
func main() {
c := &Foo{}
defaults.SetDefaults(c)
fmt.Printf("Foo: %+v", c)
}
Output:
Foo: &{ConnectionTimeout:0s}
package main
import (
"fmt"
"gopkg.in/mcuadros/go-defaults.v1"
)
func main() {
foo := &Parent{}
defaults.SetDefaults(foo)
fmt.Print(foo)
}
type Child struct {
Name string
Age int `default:"10"`
}
type Parent struct {
Children []Child
}
output: &{[]}
If you make a field's default value true
you can never set it to false. The go-defaults library will always override the false value to be true.
I made a repository with a small self contained example: link.
I don't think there is a way to fix this. Maybe go-defaults could simply ignore any bool fields. Or maybe make a custom bool type for go-defaults which keeps track of if its value has been set.
type Defaults interface {
Defaults(raw string) (interface{}, error)
}
type Duration time.Duration
func (d *Duration) Defaults(raw string) (interface{}, error) {
return time.ParseDuration(raw)
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.