最佳答案
你的意思是作为结构标签?不,不是直接。这是有充分理由的:软件库越来越多地采用“做一件事并做好”的方法。换句话说:使用正确的工具来完成工作。
但是验证你的结构很容易。您可以利用强大的github.com/asaskevich/govalidator ,例如:
package main
import (
"testing"
"github.com/asaskevich/govalidator"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type Author struct {
FirstName string `valid:"stringlength(3|20)" bson:"given_name" json:"given_name"`
LastName string `valid:"stringlength(2|20)" bson:"surname" json:"surname"`
}
type Book struct {
// Here, if ID is set, it needs to be a valid ObjectID
ID primitive.ObjectID `valid:"oid,optional" bson:"_id,omitempty" json:"_id,omitempty"`
ISBN string `valid:"isbn13,optional" bson:"isbn,omitempty" json:"isbn,omitempty"`
Title string `valid:"stringlength(5|20)" bson:"title" json:"title"`
// This instructs govalidator to validate the referenced struct, even when
// it is a pointer
Author *Author `valid:"" bson:"author" json:"author"`
}
// ObjectIDValidator validates whether the given type is a primitive.ObjectId
// and whether its value is valid.
// govalidator only validates a string as ObjectId, so we implement a little wrapper function...
func ObjectIDValidator(inner, outer interface{}) bool {
oid := inner.(primitive.ObjectID)
str := oid.Hex()
return govalidator.IsMongoID(str)
}
// ...and add it to the validators you can use as a struct tag
func init() {
govalidator.CustomTypeTagMap.Set("oid", govalidator.CustomTypeValidator(ObjectIDValidator))
}
func TestValidity(t *testing.T) {
testCases := []struct {
desc string
book Book
expectedFail bool
}{
{
desc: "A book with an invalid ISBN",
book: Book{
ID: primitive.NewObjectID(),
Title: "foobar",
ISBN: "abc",
Author: &Author{FirstName: "Foo", LastName: "Bar"},
},
expectedFail: true,
},
{
desc: "A perfectly valid (and good!) book",
book: Book{
ID: primitive.NewObjectID(),
Title: "Neuromancer",
ISBN: "978-0441569595",
Author: &Author{FirstName: "William", LastName: "Gibson"},
},
expectedFail: false,
},
{
desc: "Still a good book, but with the title cut short",
book: Book{
ID: primitive.NewObjectID(),
Title: "Neur",
ISBN: "978-0441569595",
Author: &Author{FirstName: "William", LastName: "Gibson"},
},
expectedFail: true,
},
{
desc: "Still a good book, only the author's name was cut short",
book: Book{
ID: primitive.NewObjectID(),
Title: "Neuromancer",
ISBN: "978-0441569595",
Author: &Author{FirstName: "W", LastName: "Gibson"},
},
expectedFail: true,
},
}
for _, tC := range testCases {
t.Run(tC.desc, func(t *testing.T) {
ok, err := govalidator.ValidateStruct(tC.book)
switch {
case !ok && !tC.expectedFail:
t.Errorf("%#v unexpectedly did not validate as a Book: %s", tC.book, err)
return
case ok && tC.expectedFail:
t.Errorf("%#v unexpectedly validated as a Book!", tC.book)
return
case (!ok && tC.expectedFail) || (ok && !tC.expectedFail):
t.Logf("Just as planned")
}
})
}
}
关于mongodb - Go 官方 mongo-driver 中如何实现结构体字段验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62976721/