I have model Product
with field Type
.
Something like this:
type ProductType string
var (
PtRouteTransportation ProductType = "ProductRT"
PtOnDemandTransportation ProductType = "ProductDT"
PtExcursion ProductType = "ProductEX"
PtTicket ProductType = "ProductTK"
PtQuote ProductType = "ProductQT"
PtGood ProductType = "ProductGD"
)
type Product struct {
...
Type ProductType
...
}
In Create
function I have type
form param:
type := req.Form.Get("type")
Question: how to check is type
valid?
Simplest way is:
if type != PtRouteTransportation && type != PtOnDemandTransportation && ...
but what I supposed to do if Product
will have 100 types?
How to do this in go
way?
Really the simplest is to use a map, not as fast as constants but if if you have to test against a large set, it's the most convenient way.
Also since it's pre-allocated, it's thread-safe, so you won't have to worry about locks, unless you add to it at runtime.
var (
ptTypes = map[string]struct{}{
"ProductRT": {},
"ProductDT": {},
"ProductEX": {},
"ProductTK": {},
"ProductQT": {},
"ProductGD": {},
}
)
func validType(t string) (ok bool) {
_, ok = ptTypes[t]
return
}
Instead of using a type alias to a basic type, why not using a type alias to a private type (meaning a struct you cannot initialize outside your package)
See this example.
type ProductType productType
type productType struct {
name string
}
var (
PtRouteTransportation ProductType = ProductType(productType{"ProductRT"})
PtOnDemandTransportation ProductType = ProductType(productType{"ProductDT"})
PtExcursion ProductType = ProductType(productType{"ProductEX"})
PtTicket ProductType = ProductType(productType{"ProductTK"})
PtQuote ProductType = ProductType(productType{"ProductQT"})
PtGood ProductType = ProductType(productType{"ProductGD"})
)
func printProductType(pt ProductType) {
fmt.Println(pt.name)
}
func main() {
fmt.Println("Hello, playground")
// printProductType("test") // cannot use "test" (type string) as type ProductType in argument to printProductType
printProductType(PtRouteTransportation)
}
It means you cannot use any other values than the public ones defined in the var
section.
If you manage to pass a value to the printProductType(pt ProductType
), your value is always a valid one.
For the dynamic checking part, that OneOfOne addresses in his answer, I would add a function GetProductType(name string) ProductType
which:
ProductType
instances defined in the var section above.That way, the rest of your code always work with an official ProductType value (and not with a 'string' which happens to be matching the right value)