英文:
Go How to check type of product
问题
我有一个名为Product
的模型,其中包含一个字段Type
。
类似这样的代码:
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
// ...
}
在Create
函数中,我有一个名为type
的表单参数:
type := req.Form.Get("type")
问题:如何检查type
是否有效?
最简单的方法是:
if type != PtRouteTransportation && type != PtOnDemandTransportation && ...
但是如果Product
有100种类型,我该怎么办?
在go
中如何处理这种情况?
英文:
<br>
I have model Product
with field Type
.
<br>
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")
<br>
Question: how to check is type
valid?
<br>
<br>
Simplest way is:
if type != PtRouteTransportation && type != PtOnDemandTransportation && ...
but what I supposed to do if Product
will have 100 types?
<br>
<br>
How to do this in go
way?
答案1
得分: 4
使用类型别名引用基本类型的方式,为什么不使用类型别名引用私有类型(即在包外部无法初始化的结构体)呢?
参考这个示例。
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") // 无法将类型为string的"test"用作printProductType的参数类型ProductType
printProductType(PtRouteTransportation)
}
这意味着你只能使用在var
部分定义的公共值。
如果你成功将一个值传递给printProductType(pt ProductType
),那么你的值总是有效的。
对于动态检查部分,OneOfOne在他的答案中提到,我会添加一个函数GetProductType(name string) ProductType
,该函数:
- 检查名称是否有效
- 返回在上面的
var
部分定义的官方ProductType
实例之一。
这样,你的代码的其余部分始终使用官方的ProductType值(而不是与正确值匹配的'string')。
英文:
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:
- check if the name is a valid one
- return one of the official
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)
答案2
得分: 3
最简单的方法是使用一个映射(map),虽然不如常量快,但如果你需要对一个大集合进行测试,这是最方便的方式。
另外,由于它是预分配的,所以它是线程安全的,所以你不需要担心锁的问题,除非你在运行时添加元素。
var (
ptTypes = map[string]struct{}{
"ProductRT": {},
"ProductDT": {},
"ProductEX": {},
"ProductTK": {},
"ProductQT": {},
"ProductGD": {},
}
)
func validType(t string) (ok bool) {
_, ok = ptTypes[t]
return
}
英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论