{"id":467542,"date":"2025-07-18T22:33:28","date_gmt":"2025-07-18T22:33:28","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=467542"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=467542","title":{"rendered":"<span>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 Go \u0441 go-playground\/validator: \u043f\u043e\u043b\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/656\/0a1\/22a\/6560a122a25c93c1e13fc51628b0d690.png\" width=\"780\" height=\"440\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/656\/0a1\/22a\/6560a122a25c93c1e13fc51628b0d690.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/656\/0a1\/22a\/6560a122a25c93c1e13fc51628b0d690.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h3>\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f<\/h3>\n<p>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u2014 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0430\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0411\u0435\u0437 \u043d\u0435\u0451 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u043e:<\/p>\n<ul>\n<li>\n<p>\u043f\u0430\u043d\u0438\u043a\u0430\u043c \u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u043c \u0438\u0437-\u0437\u0430 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0445 nil \u0438\u043b\u0438 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439,<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445,<\/p>\n<\/li>\n<li>\n<p>\u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044f\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 (SQL-\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438, XSS \u0438 \u0434\u0440.),<\/p>\n<\/li>\n<li>\n<p>\u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c \u0432 \u043e\u0442\u043b\u0430\u0434\u043a\u0435 \u0438\u0437-\u0437\u0430 \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0440\u0443\u0447\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0431\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a:<\/p>\n<pre><code class=\"go\">type User struct {     Name     string     Email    string     Age      int     Password string }  func (u *User) Validate() error {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u043c\u0435\u043d\u0438     if u.Name == \"\" {         return errors.New(\"name is required\")     }     if len(u.Name) &lt; 2 || len(u.Name) &gt; 50 {         return errors.New(\"name must be between 2 and 50 characters\")     }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 email     if u.Email == \"\" {         return errors.New(\"email is required\")     }     if !strings.Contains(u.Email, \"@\") {         return errors.New(\"invalid email format\")     }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430     if u.Age &lt; 18 {         return errors.New(\"age must be at least 18\")     }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0430\u0440\u043e\u043b\u044f     if len(u.Password) &lt; 8 {         return errors.New(\"password must be at least 8 characters\")     }          return nil } <\/code><\/pre>\n<h4>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430:<\/h4>\n<p>1. \u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430.<\/p>\n<pre><code class=\"go\">\/\/ \u0412 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 type Product struct { Name string } func (p *Product) Validate() error {     if p.Name == \"\" { return errors.New(\"name is required\") }     \/\/ ... \u0438 \u0442\u0430\u043a \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b } <\/code><\/pre>\n<p>2. \u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438. \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0432\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0441\u0442.<\/p>\n<p>3. \u041b\u0435\u0433\u043a\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<pre><code class=\"go\">type Registration struct {     Password        string     PasswordConfirm string } \/\/ \u0417\u0430\u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e Password == PasswordConfirm <\/code><\/pre>\n<p>4. \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 HTTP-\u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430\u043c\u0438, gRPC-\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, CLI-\u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 \u0438 \u0442. \u0434.<\/p>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 go-playground\/validator<\/h3>\n<p>go-playground\/validator \u2014 \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u00a0\u0434\u043b\u044f \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432 Go, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0435\u0451 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0440\u044f\u043c\u043e \u0432 \u0442\u0435\u0433\u0430\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440.<\/p>\n<h4>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/h4>\n<pre><code class=\"go\">go get github.com\/go-playground\/validator\/v10<\/code><\/pre>\n<h4>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430:<\/h4>\n<ul>\n<li>\n<p>\u0414\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u0433\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 \u043e\u0434\u0438\u043d \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u2014 \u043b\u0435\u0433\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0411\u043e\u0433\u0430\u0442\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u2014 \u0431\u043e\u043b\u0435\u0435 75 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041e\u0441\u043d\u043e\u0432\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0430\u043a\u0435\u0442\u043e\u043c<\/h3>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430<\/h4>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0442. \u043a. \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u2014 \u044d\u0442\u043e \u0434\u043e\u0440\u043e\u0433\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0432\u044b\u0448\u0435, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<pre><code class=\"go\">import \"github.com\/go-playground\/validator\/v10\"  \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430 var validate *validator.Validate  func init() {     validate = validator.New() }   type User struct {     Name     string `validate:\"required,min=2,max=50\"`     Email    string `validate:\"required,email\"`     Age      int    `validate:\"required,min=18\"`     Password string `validate:\"required,min=8\"` }  func main() {     user := User{         Name:     \"John Doe\",         Email:    \"john@example.com\",         Age:      25,         Password: \"securepass\",     }          err := validate.Struct(user)     if err != nil {         \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438         fmt.Println(\"Validation failed:\", err)     } } <\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0441\u0442\u0430\u043b \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0435\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u0430\u043b \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435<\/p>\n<h3>\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0442\u0435\u0433\u043e\u0432 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0430, \u043d\u0438\u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0433\u0438\u0431\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b.<\/p>\n<h4>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b:<\/h4>\n<ul>\n<li>\n<p>\u0417\u0430\u043f\u044f\u0442\u0430\u044f (,) \u2014 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0418 (\u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f).<\/p>\n<\/li>\n<li>\n<p>Pipe (|) \u2014 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0418\u041b\u0418 (\u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c\u0441\u044f).<\/p>\n<\/li>\n<li>\n<p>\u0417\u043d\u0430\u043a \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 (=) \u2014 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0431\u0435\u043b\u044b \u2014 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0430\u043c\u043e \u0441\u043e\u0431\u043e\u0439, \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0430\u0432\u0438\u043b \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0433\u0430:<\/p>\n<pre><code class=\"go\">`validate:\"rule1,rule2=param,rule3=param1|param2\"`<\/code><\/pre>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430:<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0438 \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u0442\u0435\u0433\u043e\u0432 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.<\/p>\n<pre><code class=\"go\">type Example struct { Name    string   `validate:\"required,min=2,max=50\"` Contact string   `validate:\"required_without=Phone,omitempty,email|e164\"` Phone   string   `validate:\"required_without=Contact,omitempty,e164\"` } <\/code><\/pre>\n<p>\u0412 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0432\u044b\u0448\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u043a\u0430\u043a \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438:<\/p>\n<p>\u041f\u043e\u043b\u0435 <code>Name validate:\"required,min=2,max=50\"<\/code>:<\/p>\n<ul>\n<li>\n<p><code>required <\/code>\u2014 \u043f\u043e\u043b\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c,<\/p>\n<\/li>\n<li>\n<p><code>min=2<\/code> \u2014 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 2 \u0441\u0438\u043c\u0432\u043e\u043b\u0430,<\/p>\n<\/li>\n<li>\n<p><code>max=50<\/code> \u2014 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 50 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p>\u043b\u043e\u0433\u0438\u043a\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u2014 \u043f\u043e\u043b\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043e \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0442 2 \u0434\u043e 50 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u0435 <code>validate:\"required_without=Phone,omitempty,email|e164\"<\/code>:<\/p>\n<ul>\n<li>\n<p><code>required_without=Phone<\/code> \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 <code>Phone <\/code>\u043f\u0443\u0441\u0442\u043e\u0435;\u00a0<\/p>\n<\/li>\n<li>\n<p><code>omitempty<\/code> \u2014 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0443\u044e \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u0443\u0441\u0442\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0442. \u043a. \u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0431\u0443\u0434\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438;\u00a0<\/p>\n<\/li>\n<li>\n<p><code>email <\/code>\u2014 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 email;<\/p>\n<\/li>\n<li>\n<p><code>e164<\/code> \u2014 \u043c\u0435\u0436\u0434\u0443\u043d\u0430\u0440\u043e\u0434\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 (+1234567890);\u00a0<\/p>\n<\/li>\n<li>\n<p><code>email|e164<\/code> \u2014 \u0444\u043e\u0440\u043c\u0430\u0442 email \u0438\u043b\u0438 \u0444\u043e\u0440\u043c\u0430\u0442 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 (\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u043b\u044e\u0431\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443);\u00a0<\/p>\n<\/li>\n<li>\n<p>\u043b\u043e\u0433\u0438\u043a\u0430 \u2014 \u0435\u0441\u043b\u0438 <code>Phone<\/code> \u043f\u0443\u0441\u0442\u043e\u0439, \u0442\u043e <code>Contact<\/code> \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>email<\/code> \u0438\u043b\u0438 <code>e164<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043f\u043e\u043b\u0435 <code>Contact<\/code> (\u0442\u0430\u043a\u0430\u044f \u0436\u0435 \u043b\u043e\u0433\u0438\u043a\u0430, \u043a\u0430\u043a \u0438 \u0432 <code>Phone<\/code>). \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u0435\u0433\u043e\u0432 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043c\u044b \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u043e\u043b\u0435\u0439 <code>Phone<\/code> \u0438\u043b\u0438 <code>Contact<\/code>.<\/p>\n<p>\u0412\u0410\u0416\u041d\u041e, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 <code>required_without<\/code> \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u044f <code>omitempty<\/code>, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0443\u0442 \u043f\u0440\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>omitempty<\/code> \u0441 \u044d\u0442\u0438\u043c\u0438<em> \u0442\u0435\u0433\u0430\u043c\u0438 (<\/em><a href=\"https:\/\/github.com\/go-playground\/validator\/issues\/1174#issuecomment-1983534872\" rel=\"noopener noreferrer nofollow\"><em>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/em><\/a><em>). <\/em><\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0434\u0430\u043d\u044b \u043a\u0440\u0430\u0442\u043a\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043f\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u043c \u043e\u0448\u0438\u0431\u043a\u0430\u043c:<\/p>\n<pre><code class=\"go\">func TestExampleValidation(t *testing.T) { validate := validator.New()  t.Run(\"Valid values\", func(t *testing.T) { example := Example{ Name:  \"John Doe\", Phone: \"john@example.com\", } assert.NoError(t, validate.Struct(example)) })  \/\/ \u0442\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 t.Run(\"Invalid name\", func(t *testing.T) { example := Example{Contact: \"test@example.com\"} \/\/ \u0442\u0443\u0442 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c  \u043e\u0448\u0438\u0431\u043a\u0430, \u0442.\u043a. \u043f\u043e\u043b\u0435 name \u043f\u0443\u0441\u0442\u043e\u0435 assert.Error(t, validate.Struct(example))  example.Name = \"A\" err := validate.Struct(example) \/\/ \u0430 \u0442\u0443\u0442 \u0438\u043c\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 assert.Error(t, err) })  t.Run(\"Invalid contact\", func(t *testing.T) { example := Example{Name: \"John\"} assert.Error(t, validate.Struct(example))  \/\/ \u043f\u043b\u043e\u0445\u043e\u0439 email example.Contact = \"invalid-email\" assert.Error(t, validate.Struct(example)) })  } <\/code><\/pre>\n<h3>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0435\u0433\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0442\u0435\u0433\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u043d\u043e \u043d\u0438\u0436\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u043e\u0434, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d\u0438 \u043a\u0440\u0430\u0442\u043a\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b. \u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c <a href=\"https:\/\/github.com\/go-playground\/validator\/blob\/master\/regexes.go\" rel=\"noopener noreferrer nofollow\"><em>\u0442\u0443\u0442<\/em><\/a>.<\/p>\n<h4>\u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h4>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0442\u0435\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 url, uuid \u0438 \u0442. \u0434.<\/p>\n<pre><code class=\"go\">type StringValidations struct {     Required    string `validate:\"required\"`           \/\/ \u041d\u0435 \u043f\u0443\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430     AlphaOnly   string `validate:\"alpha\"`              \/\/ \u0422\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u043a\u0432\u044b     AlphaNum    string `validate:\"alphanum\"`           \/\/ \u0411\u0443\u043a\u0432\u044b \u0438 \u0446\u0438\u0444\u0440\u044b     Numeric     string `validate:\"numeric\"`            \/\/ \u0427\u0438\u0441\u043b\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043b\u0438\u043d\u044b     MinLength   string `validate:\"min=5\"`              \/\/ \u041c\u0438\u043d\u0438\u043c\u0443\u043c 5 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432     MaxLength   string `validate:\"max=10\"`             \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 10 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432     Length      string `validate:\"len=8\"`              \/\/ \u0420\u043e\u0432\u043d\u043e 8 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432          \/\/ \u0424\u043e\u0440\u043c\u0430\u0442\u044b     Email       string `validate:\"email\"`              \/\/ Email \u0430\u0434\u0440\u0435\u0441     URL         string `validate:\"url\"`                \/\/ URL \u0430\u0434\u0440\u0435\u0441     UUID        string `validate:\"uuid\"`               \/\/ UUID \u043b\u044e\u0431\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438     UUID4       string `validate:\"uuid4\"`              \/\/ UUID \u0432\u0435\u0440\u0441\u0438\u0438 4          \/\/ \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435     Contains    string `validate:\"contains=test\"`      \/\/ \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0443     Excludes    string `validate:\"excludes=test\"`      \/\/ \u041d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0443     StartsWith  string `validate:\"startswith=Hello\"`   \/\/ \u041d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441     EndsWith    string `validate:\"endswith=World\"`     \/\/ \u0417\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430     OneOf             string  `validate:\"oneof=red green blue\"` \/\/ \u041e\u0434\u043d\u043e \u0438\u0437 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 } <\/code><\/pre>\n<h4>\u0427\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h4>\n<p>\u041f\u0430\u043a\u0435\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0433\u0438\u0431\u043a\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0435\u0439 \u0447\u0438\u0441\u0435\u043b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432\u0440\u043e\u0434\u0435 &gt;,&lt;,== \u0438 \u0442. \u0434. (<a href=\"https:\/\/github.com\/go-playground\/validator\/blob\/master\/baked_in.go#L79\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b<\/a>)<\/p>\n<pre><code class=\"go\">type NumericValidations struct {     \/\/ \u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f     GreaterThan       int     `validate:\"gt=0\"`        \/\/ &gt; 0     GreaterOrEqual    int     `validate:\"gte=18\"`      \/\/ &gt;= 18     LessThan          float64 `validate:\"lt=100.5\"`    \/\/ &lt; 100.5     LessOrEqual       float64 `validate:\"lte=99.99\"`   \/\/ &lt;= 99.99     NotEqual          int     `validate:\"ne=0\"`        \/\/ != 0     Equal             int     `validate:\"eq=0\"`        \/\/ == 0          \/\/ \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u044b     Between           int     `validate:\"min=1,max=10\"` \/\/ \u041e\u0442 1 \u0434\u043e 10 }  <\/code><\/pre>\n<h4>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439<\/h4>\n<p>\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438, \u0447\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0430\u0442, \u043f\u0430\u0440\u043e\u043b\u0435\u0439 \u0438 \u0442. \u0434.<\/p>\n<pre><code class=\"go\">type FieldComparisons struct {     Password        string `validate:\"required,min=8\"`     PasswordConfirm string `validate:\"required,eqfield=Password\"`     \/\/ \u0420\u0430\u0432\u043d\u043e \u043f\u043e\u043b\u044e Password          StartDate       string `validate:\"required\"`     EndDate         string `validate:\"required,gtfield=StartDate\"`    \/\/ \u0411\u043e\u043b\u044c\u0448\u0435 StartDate          Price           float64 `validate:\"required\"`     DiscountPrice   float64 `validate:\"ltfield=Price\"`               \/\/ \u041c\u0435\u043d\u044c\u0448\u0435 Price } <\/code><\/pre>\n<h4>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439<\/h4>\n<p>\u0410 \u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u0434\u0435\u043b \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435, \u0442. \u043a. \u0440\u044f\u0434 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u0435\u0439\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<pre><code class=\"go\">type TagsExample struct { \/\/ min=1,max=5 - \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043b-\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \/\/ dive - \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0441\u043b\u0430\u0439\u0441\u0435 \/\/ min=2,max=20 - \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043b\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0441\u043b\u0430\u0439\u0441\u0435 Tags []string `validate:\"min=1,max=5,dive,min=2,max=20\"` }  type MapExample struct { \/\/ required - \u043c\u0430\u043f\u0430 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430 (\u043d\u0435 nil) \/\/ min=1 - \u043c\u0438\u043d\u0438\u043c\u0443\u043c 1 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u043c\u0430\u043f\u0435 \/\/ dive - \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043b\u044e\u0447\u0435\u0439 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \/\/ keys,min=3,endkeys - \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043b\u044e\u0447\u0435\u0439: \u043c\u0438\u043d\u0438\u043c\u0443\u043c 3 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \/\/ required,max=100 - \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439: \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b, \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 100 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 Settings map[string]string `validate:\"required,min=1,dive,keys,min=3,endkeys,required,max=100\"` } <\/code><\/pre>\n<p>\u041e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f <code>TagsExample validate:\"min=1,max=5,dive,min=2,max=20\"<\/code><\/p>\n<ul>\n<li>\n<p><code>min=1,max=5<\/code> \u2014 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u0441\u043b\u0430\u0439\u0441\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0442 1 \u0434\u043e 5 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p><code>dive<\/code> \u2014 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u041a\u0410\u0416\u0414\u041e\u041c\u0423 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0441\u043b\u0430\u0439\u0441\u0430,<\/p>\n<\/li>\n<li>\n<p><code>min=2,max=20<\/code> \u2014 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043a \u041a\u0410\u0416\u0414\u041e\u041c\u0423 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u043f\u043e\u0441\u043b\u0435 <code>dive<\/code>, \u043a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043e\u0442 2 \u0434\u043e 20 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438:<\/p>\n<ol>\n<li>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0441\u043b\u0430\u0439\u0441\u0435 (min=1,max=5).<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0442\u043e\u043c dive \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0430 (min=2,max=20).<\/p>\n<\/li>\n<\/ol>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0442\u043e, \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u0442\u0435\u0441\u0442\u044b \u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u0438\u043c\u0438. \u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u043b\u0438 \u0444\u0430\u043a\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435\u00a0\u043d\u0438\u0436\u0435 \u043c\u044b \u0443\u0437\u043d\u0430\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0435 \u043f\u043e\u043b\u0435 \u0438 \u0442\u0435\u0433, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<pre><code class=\"go\">validationErrors := err.(validator.ValidationErrors)  assert.Equal(t, \"min\", validationErrors[0].Tag()) assert.Equal(t, \"Tags\", validationErrors[0].Field()) <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432\u0430\u0436\u043d\u043e \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0443 \u043a \u0442\u0438\u043f\u0443 validator.ValidationErrors, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0442\u0435\u0433\u0438, \u043f\u043e\u043b\u044f \u0438 \u0442. \u0434.<\/p>\n<p>\u041a\u043e\u0434 \u0442\u0435\u0441\u0442\u0430:<\/p>\n<pre><code class=\"go\">func TestTagsValidation(t *testing.T) { validate := validator.New()  t.Run(\"Empty slice\", func(t *testing.T) { example := TagsExample{ Tags: []string{}, } err := validate.Struct(example) assert.Error(t, err)  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 min \u0434\u043b\u044f \u0441\u043b\u0430\u0439\u0441\u0430 validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"min\", validationErrors[0].Tag()) assert.Equal(t, \"Tags\", validationErrors[0].Field())  })  t.Run(\"Too many tags\", func(t *testing.T) { example := TagsExample{ Tags: []string{\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\", \"tag6\"}, } err := validate.Struct(example) assert.Error(t, err)  validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"max\", validationErrors[0].Tag()) assert.Equal(t, \"Tags\", validationErrors[0].Field())  })  t.Run(\"Tag too short\", func(t *testing.T) { example := TagsExample{ Tags: []string{\"a\", \"valid\"}, } err := validate.Struct(example) assert.Error(t, err)  validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"min\", validationErrors[0].Tag()) assert.Contains(t, validationErrors[0].Namespace(), \"Tags[0]\") })  t.Run(\"Tag too long\", func(t *testing.T) { tooLongTag := \"tooooooooooooooooooooooolooooooooooooooooooooooong\" example := TagsExample{ Tags: []string{\"valid\", tooLongTag}, } err := validate.Struct(example) assert.Error(t, err)  validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"max\", validationErrors[0].Tag()) assert.Contains(t, validationErrors[0].Namespace(), \"Tags[1]\")  })  t.Run(\"Multiple validation errors\", func(t *testing.T) { example := TagsExample{ \/\/ \u0434\u0432\u0430 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u0442\u0435\u0433\u0430 Tags: []string{\"x\", \"valid\", \"y\"}, } err := validate.Struct(example) assert.Error(t, err)  validationErrors := err.(validator.ValidationErrors) \/\/\u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c 2 \u043e\u0448\u0438\u0431\u043a\u0438 assert.Len(t, validationErrors, 2)  for _, fieldError := range validationErrors { assert.Equal(t, \"min\", fieldError.Tag()) assert.Contains(t, fieldError.Namespace(), \"Tags[\") }  })  } <\/code><\/pre>\n<p>\u041e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 map <code><em>validate:\"required,min=1,dive,keys, min=3,endkeys,required,max=100\"<\/em><\/code>. \u041b\u043e\u0433\u0438\u043a\u0430 \u0434\u043b\u044f map \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u0432\u0441\u0451 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>r<code>equired<\/code> \u2014 \u043c\u0430\u043f\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c nil,<\/p>\n<\/li>\n<li>\n<p><code>min=1<\/code> \u2014 \u043c\u0438\u043d\u0438\u043c\u0443\u043c 1 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u043c\u0430\u043f\u0435,<\/p>\n<\/li>\n<li>\n<p><code>dive<\/code> \u2014 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u0430\u0440 \u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435,<\/p>\n<\/li>\n<li>\n<p><code>keys<\/code> \u2014 \u043d\u0430\u0447\u0430\u043b\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u041a\u041b\u042e\u0427\u0415\u0419,<\/p>\n<\/li>\n<li>\n<p><code>min=3<\/code> \u2014 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u044e\u0447 \u043c\u0438\u043d\u0438\u043c\u0443\u043c 3 \u0441\u0438\u043c\u0432\u043e\u043b\u0430,<\/p>\n<\/li>\n<li>\n<p><code>endkeys<\/code> \u2014 \u043a\u043e\u043d\u0435\u0446 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043b\u044e\u0447\u0435\u0439,<\/p>\n<\/li>\n<li>\n<p><code>required<\/code> \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c,<\/p>\n<\/li>\n<li>\n<p><code>max=100<\/code> \u2014 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 100 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u041e\u0420\u042f\u0414\u041e\u041a \u041f\u0420\u041e\u0412\u0415\u0420\u041a\u0418:<\/p>\n<ol>\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0430\u043c\u043e\u0439 \u043c\u0430\u043f\u044b (<code>required, min=1<\/code>).<\/p>\n<\/li>\n<li>\n<p><code>dive<\/code> \u2014 \u0432\u0445\u043e\u0434\u0438\u043c \u0432 \u043c\u0430\u043f\u0443 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u044b \u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435: <br \/>a) \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043a\u043b\u044e\u0447 (\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043c\u0435\u0436\u0434\u0443 <code>keys<\/code> \u0438 <code>endkeys<\/code>), <br \/>b) \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u043e\u0441\u043b\u0435 <code>endkeys<\/code>).<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u0430\u0436\u043d\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b:<\/p>\n<ol>\n<li>\n<p><code>keys...endkeys<\/code> \u2014 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0422\u041e\u041b\u042c\u041a\u041e \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0435\u0439 \u043c\u0430\u043f\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u043e\u0441\u043b\u0435 <code>endkeys<\/code> \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u0430\u043f\u044b \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d.<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u043e\u0434 \u0442\u0435\u0441\u0442\u043e\u0432, \u0433\u0434\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0434\u043b\u044f <code>map<\/code>:<\/p>\n<pre><code class=\"go\">func TestMapValidation(t *testing.T) { validate := validator.New()  t.Run(\"Empty map\", func(t *testing.T) { example := MapExample{ Settings: map[string]string{}, } err := validate.Struct(example) assert.Error(t, err)  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 min \u0434\u043b\u044f \u043c\u0430\u043f\u044b validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"min\", validationErrors[0].Tag()) assert.Equal(t, \"Settings\", validationErrors[0].Field()) })  t.Run(\"Nil map\", func(t *testing.T) { example := MapExample{ Settings: nil, \/\/ nil \u043c\u0430\u043f\u0430 } err := validate.Struct(example) assert.Error(t, err)  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 required validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"required\", validationErrors[0].Tag()) assert.Equal(t, \"Settings\", validationErrors[0].Field()) })  t.Run(\"Key too short\", func(t *testing.T) { example := MapExample{ Settings: map[string]string{ \/\/ \u043a\u043b\u044e\u0447 \u0432\u0441\u0435\u0433\u043e 2 \u0441\u0438\u043c\u0432\u043e\u043b\u0430, \u043d\u0443\u0436\u043d\u043e \u043c\u0438\u043d\u0438\u043c\u0443\u043c 3  \"ab\": \"valid value\",  }, } err := validate.Struct(example) assert.Error(t, err)  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0430 validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"min\", validationErrors[0].Tag()) \/\/ Namespace \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c Settings[ab] - \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 assert.Contains(t, validationErrors[0].Namespace(), \"Settings[ab]\") })  t.Run(\"Empty value\", func(t *testing.T) { example := MapExample{ Settings: map[string]string{ \"key1\": \"\", \/\/ \u043f\u0443\u0441\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043d\u043e required \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0435\u043f\u0443\u0441\u0442\u043e\u0435 }, } err := validate.Struct(example) assert.Error(t, err)  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f validationErrors := err.(validator.ValidationErrors) assert.Equal(t, \"required\", validationErrors[0].Tag()) assert.Contains(t, validationErrors[0].Namespace(), \"Settings[key1]\") })   t.Run(\"Multiple errors\", func(t *testing.T) { example := MapExample{ Settings: map[string]string{ \"k1\":       \"valid\",         \/\/ \u043a\u043b\u044e\u0447 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \"validKey\": \"\",              \/\/ \u043f\u0443\u0441\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \"ok\":       \"another value\", \/\/ \u043a\u043b\u044e\u0447 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 }, } err := validate.Struct(example) assert.Error(t, err)  \/\/ \u0414\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c  3 \u043e\u0448\u0438\u0431\u043a\u0438 validationErrors := err.(validator.ValidationErrors) assert.Equal(t, len(validationErrors), 3)  \/\/ \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0442\u0438\u043f\u044b \u043e\u0448\u0438\u0431\u043e\u043a errorTags := make(map[string]int) for _, fieldError := range validationErrors { errorTags[fieldError.Tag()]++ }  \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0431\u043e\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 assert.GreaterOrEqual(t, errorTags[\"min\"], 2)      \/\/ \u043c\u0438\u043d\u0438\u043c\u0443\u043c 2 \u043e\u0448\u0438\u0431\u043a\u0438 min (\u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u043a\u043b\u044e\u0447\u0438) assert.GreaterOrEqual(t, errorTags[\"required\"], 1) \/\/ \u043c\u0438\u043d\u0438\u043c\u0443\u043c 1 \u043e\u0448\u0438\u0431\u043a\u0430 required (\u043f\u0443\u0441\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435) })  t.Run(\"Valid map\", func(t *testing.T) { example := MapExample{ Settings: map[string]string{ \"timeout\":    \"30s\", \"retryCount\": \"3\", \"debug\":      \"true\", }, } err := validate.Struct(example) assert.NoError(t, err) \/\/ \u041d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u043a })  \/\/\u0413\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 t.Run(\"Edge cases\", func(t *testing.T) { \/\/ \u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0432\u0430\u043b\u0438\u0434\u043d\u0430\u044f \u043c\u0430\u043f\u0430 example := MapExample{ Settings: map[string]string{ \"key\": \"v\", \/\/ \u043a\u043b\u044e\u0447 \u0440\u043e\u0432\u043d\u043e 3 \u0441\u0438\u043c\u0432\u043e\u043b\u0430, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 }, } err := validate.Struct(example) assert.NoError(t, err)  \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u043d\u043e\u0435 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u0440\u043e\u0432\u043d\u043e 100 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432) maxValue := \"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\" example2 := MapExample{ Settings: map[string]string{ \"key\": maxValue, }, } err2 := validate.Struct(example2) assert.NoError(t, err2) })  } <\/code><\/pre>\n<h3>\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u044b<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430 \u043f\u043e\u043b\u044f \u043d\u0443\u0436\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439 <code>func(fl validator.FieldLevel) bool<\/code>. \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>validator.FieldLevel<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c\u043e\u043c\u0443 \u043f\u043e\u043b\u044e \u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"go\">func validateStrongPassword(fl validator.FieldLevel) bool {     password := fl.Field().String()          if len(password) &lt; 8 {        return false     }          hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password)     hasDigit := regexp.MustCompile(`[0-9]`).MatchString(password)          return hasUpper &amp;&amp; hasDigit } <\/code><\/pre>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432, \u0441\u0432\u043e\u0438 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c:<\/p>\n<pre><code class=\"go\">validate := validator.New() validate.RegisterValidation(\"strong_password\", validateStrongPassword) <\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043a\u043e \u0432\u0441\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 func(sl validator.StructLevel):<\/p>\n<pre><code class=\"go\">func validateShoppingCart(sl validator.StructLevel) {     cart := sl.Current().Interface().(ShoppingCart)          \/\/ \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0442\u043e\u0432\u0430\u0440\u044b, \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438     if len(cart.Items) &gt; 0 &amp;&amp; cart.DeliveryAddress == \"\" {        sl.ReportError(cart.DeliveryAddress, \"DeliveryAddress\", \"DeliveryAddress\", \"address_required\", \"\")     }          \/\/ \u0414\u043b\u044f \u0437\u0430\u043a\u0430\u0437\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 5000 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u043e \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0443     if cart.TotalAmount &gt; 5000 &amp;&amp; cart.PhoneConfirmed == false {        sl.ReportError(cart.PhoneConfirmed, \"PhoneConfirmed\", \"PhoneConfirmed\", \"phone_confirm_required\", \"\")     } } <\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>ReportError<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c \u0442\u0435\u0433\u043e\u043c. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432, \u0433\u0434\u0435 \u0442\u0435\u0433\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 (<code>required, min, max<\/code>), \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0435\u0433\u0430 \u043e\u0448\u0438\u0431\u043a\u0438:<\/p>\n<pre><code class=\"go\">sl.ReportError( cart.PhoneConfirmed,      \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \"PhoneConfirmed\",         \/\/ \u0438\u043c\u044f \u043f\u043e\u043b\u044f \u0434\u043b\u044f namespace \"PhoneConfirmed\",         \/\/ \u0438\u043c\u044f \u043f\u043e\u043b\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \"phone_confirm_required\", \/\/ \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u0433 \u043e\u0448\u0438\u0431\u043a\u0438 \"\"                       \/\/ \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e) ) <\/code><\/pre>\n<p>\u0422\u0435\u0433 <code>\"phone_confirm_required\"<\/code> \u2014 \u044d\u0442\u043e \u043d\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0442\u0435\u0433 \u0438\u0437 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438. \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"go\">validate := validator.New() validate.RegisterStructValidation(validateShoppingCart, ShoppingCart{}) <\/code><\/pre>\n<p>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0438\u0447\u0435\u043c \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0445:<\/p>\n<pre><code class=\"go\">t.Run(\"Too short\", func(t *testing.T) {     reg := Registration{         Email:    \"user@mail.ru\",         Password: \"Pass1\",     }     err := validate.Struct(reg)     assert.Error(t, err) })  t.Run(\"Items without address\", func(t *testing.T) {     cart := ShoppingCart{         Items:           []string{\"\u0422\u043e\u0432\u0430\u04401\", \"\u0422\u043e\u0432\u0430\u04402\"},         DeliveryAddress: \"\",         TotalAmount:     3000,         PhoneConfirmed:  false,     }     err := validate.Struct(cart)     assert.Error(t, err)      validationErrors := err.(validator.ValidationErrors)     assert.Equal(t, \"DeliveryAddress\", validationErrors[0].Field()) })  t.Run(\"Large amount without confirmation\", func(t *testing.T) {     cart := ShoppingCart{         Items:           []string{\"\u0414\u043e\u0440\u043e\u0433\u043e\u0439 \u0442\u043e\u0432\u0430\u0440\"},         DeliveryAddress: \"\u0443\u043b. \u041b\u0435\u043d\u0438\u043d\u0430, \u0434. 1\",         TotalAmount:     6000,         PhoneConfirmed:  false,     }     err := validate.Struct(cart)     assert.Error(t, err)      validationErrors := err.(validator.ValidationErrors)     assert.Equal(t, \"PhoneConfirmed\", validationErrors[0].Field()) }) <\/code><\/pre>\n<p>\u041a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0435\u0439 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a \u0442\u0438\u043f\u0443 <code>validator.ValidationErrors<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435: \u043a\u0430\u043a\u043e\u0435 \u043f\u043e\u043b\u0435 \u043d\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0438 \u043a\u0430\u043a\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u043e.<\/p>\n<h3>\u0420\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b<\/h3>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0443\u0434\u043e\u0431\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445 \u0438\u043b\u0438 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"go\">\/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b type User struct {     Name  string     Email string     Age   int }  \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 rules := map[string]string{     \"Name\":  \"required,min=2,max=50\",     \"Email\": \"required,email\",     \"Age\":   \"required,min=18,max=120\", }  \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b validate.RegisterStructValidationMapRules(rules, User{})  <\/code><\/pre>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>go-playground\/validator<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0435 \u0438 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043e\u0434 \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0434\u0451\u0436\u043d\u044b\u043c \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u043c.<\/p>\n<p><strong>\u0410\u0432\u0442\u043e\u0440 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430\u00a0<\/strong><a href=\"https:\/\/habr.com\/ru\/users\/alex_name_m\/\" rel=\"noopener noreferrer nofollow\"><strong>alex_name_m<\/strong><\/a><\/p>\n<hr\/>\n<p>\u041d\u041b\u041e \u043f\u0440\u0438\u043b\u0435\u0442\u0435\u043b\u043e \u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u043c\u043e\u043a\u043e\u0434 \u0434\u043b\u044f \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u0433\u0430:<br \/>\u2014\u00a0<a href=\"https:\/\/firstvds.ru\/?utm_source=habr&amp;utm_medium=article&amp;utm_campaign=product&amp;utm_content=vds15exeptprogrev\" rel=\"noopener noreferrer nofollow\">15% \u043d\u0430 \u0437\u0430\u043a\u0430\u0437 \u043b\u044e\u0431\u043e\u0433\u043e VDS<\/a>\u00a0(\u043a\u0440\u043e\u043c\u0435 \u0442\u0430\u0440\u0438\u0444\u0430 \u041f\u0440\u043e\u0433\u0440\u0435\u0432) \u2014\u00a0<strong>HABRFIRSTVDS<\/strong>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/927460\/\"> https:\/\/habr.com\/ru\/articles\/927460\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<h3>\u0417\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f<\/h3>\n<p>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u2014 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0430\u0436\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0411\u0435\u0437 \u043d\u0435\u0451 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u043e:<\/p>\n<ul>\n<li>\n<p>\u043f\u0430\u043d\u0438\u043a\u0430\u043c \u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u043c \u0438\u0437-\u0437\u0430 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0445 nil \u0438\u043b\u0438 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439,<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445,<\/p>\n<\/li>\n<li>\n<p>\u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044f\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 (SQL-\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438, XSS \u0438 \u0434\u0440.),<\/p>\n<\/li>\n<li>\n<p>\u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c \u0432 \u043e\u0442\u043b\u0430\u0434\u043a\u0435 \u0438\u0437-\u0437\u0430 \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0440\u0443\u0447\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0431\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a:<\/p>\n<pre><code class=\"go\">type User struct {     Name     string     Email    string     Age      int     Password string }  func (u *User) Validate() error {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u043c\u0435\u043d\u0438     if u.Name == \"\" {         return errors.New(\"name is required\")     }     if len(u.Name) &lt; 2 || len(u.Name) &gt; 50 {         return errors.New(\"name must be between 2 and 50 characters\")     }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 email     if u.Email == \"\" {         return errors.New(\"email is required\")     }     if !strings.Contains(u.Email, \"@\") {         return errors.New(\"invalid email format\")     }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430     if u.Age &lt; 18 {         return errors.New(\"age must be at least 18\")     }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0430\u0440\u043e\u043b\u044f     if len(u.Password) &lt; 8 {         return errors.New(\"password must be at least 8 characters\")     }          return nil } <\/code><\/pre>\n<h4>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430:<\/h4>\n<p>1. \u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430.<\/p>\n<pre><code class=\"go\">\/\/ \u0412 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 type Product struct { Name string } func (p *Product) Validate() error {     if p.Name == \"\" { return errors.New(\"name is required\") }     \/\/ ... \u0438 \u0442\u0430\u043a \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b } <\/code><\/pre>\n<p>2. \u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438. \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0432\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u0441\u0442.<\/p>\n<p>3. \u041b\u0435\u0433\u043a\u043e \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<pre><code class=\"go\">type Registration struct {     Password        string     PasswordConfirm string } \/\/ \u0417\u0430\u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e Password == PasswordConfirm <\/code><\/pre>\n<p>4. \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0436\u0434\u0443 HTTP-\u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430\u043c\u0438, gRPC-\u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, CLI-\u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438 \u0438 \u0442. \u0434.<\/p>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 go-playground\/validator<\/h3>\n<p>go-playground\/validator \u2014 \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u00a0\u0434\u043b\u044f \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0432 Go, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0435\u0451 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0440\u044f\u043c\u043e \u0432 \u0442\u0435\u0433\u0430\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440.<\/p>\n<h4>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/h4>\n<pre><code class=\"go\">go get github.com\/go-playground\/validator\/v10<\/code><\/pre>\n<h4>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430:<\/h4>\n<ul>\n<li>\n<p>\u0414\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u2014 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u0433\u0430\u0445.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 \u043e\u0434\u0438\u043d \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u2014 \u043b\u0435\u0433\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0411\u043e\u0433\u0430\u0442\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u2014 \u0431\u043e\u043b\u0435\u0435 75 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<h3>\u041e\u0441\u043d\u043e\u0432\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0430\u043a\u0435\u0442\u043e\u043c<\/h3>\n<h4>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430<\/h4>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0442. \u043a. \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u2014 \u044d\u0442\u043e \u0434\u043e\u0440\u043e\u0433\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0432\u044b\u0448\u0435, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<pre><code class=\"go\">import \"github.com\/go-playground\/validator\/v10\"  \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430 var validate *validator.Validate  func init() {     validate = validator.New() }   type User struct {     Name     string `validate:\"required,min=2,max=50\"`     Email    string `validate:\"required,email\"`     Age      int    `validate:\"required,min=18\"`     Password string `validate:\"required,min=8\"` }  func main() {     user := User{         Name:     \"John Doe\",         Email:    \"john@example.com\",         Age:      25,         Password: \"securepass\",     }          err := validate.Struct(user)     if err != nil {         \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438         fmt.Println(\"Validation failed:\", err)     } } <\/code><\/pre>\n<p>\u041a\u043e\u0434 \u0441\u0442\u0430\u043b \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u0435\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u0430\u043b \u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435<\/p>\n<h3>\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0442\u0435\u0433\u043e\u0432 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c \u043f\u0430\u043a\u0435\u0442\u0430, \u043d\u0438\u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0433\u0438\u0431\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b.<\/p>\n<h4>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b:<\/h4>\n<ul>\n<li>\n<p>\u0417\u0430\u043f\u044f\u0442\u0430\u044f (,) \u2014 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0418 (\u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f).<\/p>\n<\/li>\n<li>\n<p>Pipe (|) \u2014 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0418\u041b\u0418 (\u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c\u0441\u044f).<\/p>\n<\/li>\n<li>\n<p>\u0417\u043d\u0430\u043a \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430 (=) \u2014 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0431\u0435\u043b\u044b \u2014 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0430\u043c\u043e \u0441\u043e\u0431\u043e\u0439, \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0430\u0432\u0438\u043b \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0433\u0430:<\/p>\n<pre><code class=\"go\">`validate:\"rule1,rule2=param,rule3=param1|param2\"`<\/code><\/pre>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430:<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0438 \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u0442\u0435\u0433\u043e\u0432 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.<\/p>\n<pre><code class=\"go\">type Example struct { Name    string   `validate:\"required,min=2,max=50\"` Contact string   `validate:\"required_without=Phone,omitempty,email|e164\"` Phone   string   `validate:\"required_without=Contact,omitempty,e164\"` } <\/code><\/pre>\n<p>\u0412 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0432\u044b\u0448\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0442\u0438\u043f\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f, \u043a\u0430\u043a \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438:<\/p>\n<p>\u041f\u043e\u043b\u0435 <code>Name validate:\"required,min=2,max=50\"<\/code>:<\/p>\n<ul>\n<li>\n<p><code>required <\/code>\u2014 \u043f\u043e\u043b\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c,<\/p>\n<\/li>\n<li>\n<p><code>min=2<\/code> \u2014 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 2 \u0441\u0438\u043c\u0432\u043e\u043b\u0430,<\/p>\n<\/li>\n<li>\n<p><code>max=50<\/code> \u2014 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 50 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p>\u043b\u043e\u0433\u0438\u043a\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u2014 \u043f\u043e\u043b\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043e \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0442 2 \u0434\u043e 50 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u043b\u0435 <code>validate:\"required_without=Phone,omitempty,email|e164\"<\/code>:<\/p>\n<ul>\n<li>\n<p><code>required_without=Phone<\/code> \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 <code>Phone <\/code>\u043f\u0443\u0441\u0442\u043e\u0435;\u00a0<\/p>\n<\/li>\n<li>\n<p><code>omitempty<\/code> \u2014 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0443\u044e \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u0443\u0441\u0442\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0442. \u043a. \u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0431\u0443\u0434\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438;\u00a0<\/p>\n<\/li>\n<li>\n<p><code>email <\/code>\u2014 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 email;<\/p>\n<\/li>\n<li>\n<p><code>e164<\/code> \u2014 \u043c\u0435\u0436\u0434\u0443\u043d\u0430\u0440\u043e\u0434\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 (+1234567890);\u00a0<\/p>\n<\/li>\n<li>\n<p><code>email|e164<\/code> \u2014 \u0444\u043e\u0440\u043c\u0430\u0442 email \u0438\u043b\u0438 \u0444\u043e\u0440\u043c\u0430\u0442 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 (\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u043b\u044e\u0431\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443);\u00a0<\/p>\n<\/li>\n<li>\n<p>\u043b\u043e\u0433\u0438\u043a\u0430 \u2014 \u0435\u0441\u043b\u0438 <code>Phone<\/code> \u043f\u0443\u0441\u0442\u043e\u0439, \u0442\u043e <code>Contact<\/code> \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>email<\/code> \u0438\u043b\u0438 <code>e164<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043f\u043e\u043b\u0435 <code>Contact<\/code> (\u0442\u0430\u043a\u0430\u044f \u0436\u0435 \u043b\u043e\u0433\u0438\u043a\u0430, \u043a\u0430\u043a \u0438 \u0432 <code>Phone<\/code>). \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u0435\u0433\u043e\u0432 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043c\u044b \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e \u0438\u0437 \u0434\u0432\u0443\u0445 \u043f\u043e\u043b\u0435\u0439 <code>Phone<\/code> \u0438\u043b\u0438 <code>Contact<\/code>.<\/p>\n<p>\u0412\u0410\u0416\u041d\u041e, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 <code>required_without<\/code> \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u044f <code>omitempty<\/code>, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0443\u0442 \u043f\u0440\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>omitempty<\/code> \u0441 \u044d\u0442\u0438\u043c\u0438<em> \u0442\u0435\u0433\u0430\u043c\u0438 (<\/em><a href=\"https:\/\/github.com\/go-playground\/validator\/issues\/1174#issuecomment-1983534872\" rel=\"noopener noreferrer nofollow\"><em>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/em><\/a><em>). <\/em><\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0434\u0430\u043d\u044b \u043a\u0440\u0430\u0442\u043a\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043f\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u043c \u043e\u0448\u0438\u0431\u043a\u0430\u043c:<\/p>\n<pre><code class=\"go\">func TestExampleValidation(t *testing.T) { validate := validator.New()  t.Run(\"Valid values\", func(t *testing.T) { example := Example{ Name:  \"John Doe\", Phone: \"john@example.com\", } assert.NoError(t, validate.Struct(example)) })  \/\/ \u0442\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 t.Run(\"Invalid name\", func(t *testing.T) { example := Example{Contact: \"test@example.com\"} \/\/ \u0442\u0443\u0442 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c  \u043e\u0448\u0438\u0431\u043a\u0430, \u0442.\u043a. \u043f\u043e\u043b\u0435 name \u043f\u0443\u0441\u0442\u043e\u0435 assert.Error(t, validate.Struct(example))  example.Name = \"A\" err := validate.Struct(example) \/\/ \u0430 \u0442\u0443\u0442 \u0438\u043c\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 assert.Error(t, err) })  t.Run(\"Invalid contact\", func(t *testing.T) { example := Example{Name: \"John\"} assert.Error(t, validate.Struct(example))  \/\/ \u043f\u043b\u043e\u0445\u043e\u0439 email example.Contact = \"invalid-email\" assert.Error(t, validate.Struct(example)) })  } <\/code><\/pre>\n<h3>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u0435\u0433\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h3>\n<p>\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0442\u0435\u0433\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u043d\u043e \u043d\u0438\u0436\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u043e\u0434, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d\u0438 \u043a\u0440\u0430\u0442\u043a\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b. \u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0437\u043d\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c <a href=\"https:\/\/github.com\/go-playground\/validator\/blob\/master\/regexes.go\" rel=\"noopener noreferrer nofollow\"><em>\u0442\u0443\u0442<\/em><\/a>.<\/p>\n<h4>\u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h4>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0442\u0435\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 url, uuid \u0438 \u0442. \u0434.<\/p>\n<pre><code class=\"go\">type StringValidations struct {     Required    string `validate:\"required\"`           \/\/ \u041d\u0435 \u043f\u0443\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430     AlphaOnly   string `validate:\"alpha\"`              \/\/ \u0422\u043e\u043b\u044c\u043a\u043e \u0431\u0443\u043a\u0432\u044b     AlphaNum    string `validate:\"alphanum\"`           \/\/ \u0411\u0443\u043a\u0432\u044b \u0438 \u0446\u0438\u0444\u0440\u044b     Numeric     string `validate:\"numeric\"`            \/\/ \u0427\u0438\u0441\u043b\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043b\u0438\u043d\u044b     MinLength   string `validate:\"min=5\"`              \/\/ \u041c\u0438\u043d\u0438\u043c\u0443\u043c 5 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432     MaxLength   string `validate:\"max=10\"`             \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 10 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432     Length      string `validate:\"len=8\"`              \/\/ \u0420\u043e\u0432\u043d\u043e 8 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432          \/\/ \u0424\u043e\u0440\u043c\u0430\u0442\u044b     Email       string `validate:\"email\"`              \/\/ Email \u0430\u0434\u0440\u0435\u0441     URL         string `validate:\"url\"`                \/\/ URL \u0430\u0434\u0440\u0435\u0441     UUID        string `validate:\"uuid\"`               \/\/ UUID \u043b\u044e\u0431\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438     UUID4       string `validate:\"uuid4\"`              \/\/ UUID \u0432\u0435\u0440\u0441\u0438\u0438 4          \/\/ \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435     Contains    string `validate:\"contains=test\"`      \/\/ \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0443     Excludes    string `validate:\"excludes=test\"`      \/\/ \u041d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a\u0443     StartsWith  string `validate:\"startswith=Hello\"`   \/\/ \u041d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441     EndsWith    string `validate:\"endswith=World\"`     \/\/ \u0417\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430     OneOf             string  `validate:\"oneof=red green blue\"` \/\/ \u041e\u0434\u043d\u043e \u0438\u0437 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 } <\/code><\/pre>\n<h4>\u0427\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h4>\n<p>\u041f\u0430\u043a\u0435\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0433\u0438\u0431\u043a\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0435\u0439 \u0447\u0438\u0441\u0435\u043b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432\u0440\u043e\u0434\u0435 &gt;,&lt;,== \u0438 \u0442. \u0434. (<a href=\"https:\/\/github.com\/go-playground\/validator\/blob\/master\/baked_in.go#L79\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b<\/a>)<\/p>\n<pre><code class=\"go\">type NumericValidations struct {     \/\/ \u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f     GreaterThan       int     `validate:\"gt=0\"`        \/\/ &gt; 0     GreaterOrEqual    int     `validate:\"gte=18\"`      \/\/ &gt;= 18     LessThan          float64 `validate:\"lt=100.5\"`    \/\/ &lt; 100.5     LessOrEqual       float64 `validate:\"lte=99.99\"`   \/\/ &lt;= 99.99     NotEqual          int     `validate:\"ne=0\"`        \/\/ != 0     Equal             int     `validate:\"eq=0\"`        \/\/ == 0          \/\/ \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u044b     Between           int     `validate:\"min=1,max=10\"` \/\/ \u041e\u0442 1 \u0434\u043e 10 }  <\/code><\/pre>\n<h4>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439<\/h4>\n<p>\u041f\u0430\u043a\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438, \u0447\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0430\u0442, \u043f\u0430\u0440\u043e\u043b\u0435\u0439 \u0438 \u0442. \u0434.<\/p>\n<pre><code class=\"go\">type FieldComparisons struct {     Password        string `validate:\"required,min=8\"`     PasswordConfirm string `validate:\"required,eqfield=Password\"`     \/\/ \u0420\u0430\u0432\u043d\u043e \u043f\u043e\u043b\u044e Password          StartDate       string `validate:\"required\"`     EndDate         string `validate:\"required,gtfield=StartDate\"`    \/\/ \u0411\u043e\u043b\u044c\u0448\u0435 StartDate          Price           float64 `validate:\"required\"`     DiscountPrice   float64 `validate:\"ltfield=Price\"`               \/\/ \u041c\u0435\u043d\u044c\u0448\u0435 Price } <\/code><\/pre>\n<h4>\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439<\/h4>\n<p>\u0410 \u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u0434\u0435\u043b \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435, \u0442. \u043a. \u0440\u044f\u0434 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u0435\u0439\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<pre><code class=\"go\">type TagsExample struct { \/\/ min=1,max=5 - \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043b-\u0432\u043e<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-467542","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/467542","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=467542"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/467542\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=467542"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=467542"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=467542"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}