구조체에서 기본형을 배제하다
개요
Go는 개념 표현이 쉬운 언어다.
기본 구조체를 사용하다
type User struct {
Name string
Email string
}
개념 모델을 깨닫기 시작하면 위의 코드를 보면 Name과 Email은 다른 개념이어야 하지만 같은 유형의 사람들은 구역질이 난다.Go의 경우 Defined Type을 사용해 구조체에서 기본형을 제외할 수 있다.
기본형의 배제
type Name string
type Email string
type User struct {
Name Name
Email Email
}
Name
와 Email
의 개념은 이미 분리되었다.이 하나만으로도 외출 후에는 별명만 붙이고 Go는 구조적으로 틀을 붙이는데 여기에 덧붙이면 콘셉트 표현도 정교해진다.
예를 들어 다음과 같은 검증을 실현할 수 있다.
package main
import (
"fmt"
"reflect"
"strings"
)
type Name string
type Email string
type User struct {
Name Name
Email Email
}
// ValidationProp は検査対象プロパティ
type ValidationProp interface {
IsValid() bool
}
// IsValid は Email が定義域内かを検証する
func (src Email) IsValid() bool {
// @ を含まないものは不可
return strings.Contains(string(src), "@")
}
// Check は構造体内のプロパティが定義域内かを検証する
func Check(value interface{}) bool {
v := reflect.ValueOf(value)
t := v.Type()
// 構造体のプロパティを 1つずつ確認
for i := 0; i < t.NumField(); i++ {
fv := v.Field(i)
// ValidationProp 型の場合は検証する
if prop, ok := fv.Interface().(ValidationProp); ok {
if !prop.IsValid() {
return false
}
}
}
return true
}
func main() {
alice := User{Name: "Alice", Email: "[email protected]"}
fmt.Printf("User: %+v, Check: %t\n", alice, Check(alice))
// => User: {Name:Alice Email:[email protected]}, Check: true
bob := User{Name: "Bob", Email: "bob email"}
fmt.Printf("User: %+v, Check: %t\n", bob, Check(bob))
// => User: {Name:Bob Email:bob email}, Check: false
}
위 코드에서
IsValid()
방법이 정의한 유형을 ValidationProp
Check()
패브릭에 포함된 ValidationProp
의 적절성 결정 Email
형에 정의IsValid()
를 통해Check()
의 검사 대상에 포함"따라서 예를 들어,""비워두기
Name
""조건이 추가된 경우func (src Name) IsValid() bool {
return src != ""
}
만 추가하면 됩니다.추가 코드 전문
package main
import (
"fmt"
"reflect"
"strings"
)
type Name string
type Email string
type User struct {
Name Name
Email Email
}
// ValidationProp は検査対象プロパティ
type ValidationProp interface {
IsValid() bool
}
// IsValid は Email が定義域内かを検証する
func (src Email) IsValid() bool {
// @ を含まないものは不可
return strings.Contains(string(src), "@")
}
// IsValid は Name が定義域内かを検証する
func (src Name) IsValid() bool {
return src != ""
}
// Check は構造体内のプロパティが定義域内かを検証する
func Check(value interface{}) bool {
v := reflect.ValueOf(value)
t := v.Type()
// 構造体のプロパティを 1つずつ確認
for i := 0; i < t.NumField(); i++ {
fv := v.Field(i)
// ValidationProp 型の場合は検証する
if prop, ok := fv.Interface().(ValidationProp); ok {
if !prop.IsValid() {
return false
}
}
}
return true
}
func main() {
alice := User{Name: "Alice", Email: "[email protected]"}
fmt.Printf("User: %+v, Check: %t\n", alice, Check(alice))
// => User: {Name:Alice Email:[email protected]}, Check: true
bob := User{Name: "Bob", Email: "bob email"}
fmt.Printf("User: %+v, Check: %t\n", bob, Check(bob))
// => User: {Name:Bob Email:bob email}, Check: false
anonymous := User{Name: "", Email: "[email protected]"}
fmt.Printf("User: %+v, Check: %t\n", anonymous , Check(anonymous ))
// => User: {Name: Email:[email protected]}, Check: false
}
이처럼 Go는 개념을 절분하고 나중에 추가하는 것이 수월해 콘셉트 모델을 활용하기 쉽다.
덤
매립을 통해 (하고 싶다면) 이런 정의를 내릴 수 있다.
type Name string
type Email string
type User struct {
Name
Email
}
변경 후 코드 전문package main
import (
"fmt"
"reflect"
"strings"
)
type Name string
type Email string
type User struct {
Name
Email
}
// ValidationProp は検査対象プロパティ
type ValidationProp interface {
IsValid() bool
}
// IsValid は Email が定義域内かを検証する
func (src Email) IsValid() bool {
// @ を含まないものは不可
return strings.Contains(string(src), "@")
}
// Check は構造体内のプロパティが定義域内かを検証する
func Check(value interface{}) bool {
v := reflect.ValueOf(value)
t := v.Type()
// 構造体のプロパティを 1つずつ確認
for i := 0; i < t.NumField(); i++ {
fv := v.Field(i)
// ValidationProp 型の場合は検証する
if prop, ok := fv.Interface().(ValidationProp); ok {
if !prop.IsValid() {
return false
}
}
}
return true
}
func main() {
alice := User{Name: "Alice", Email: "[email protected]"}
fmt.Printf("User: %+v, Check: %t\n", alice, Check(alice))
// => User: {Name:Alice Email:[email protected]}, Check: true
bob := User{Name: "Bob", Email: "bob email"}
fmt.Printf("User: %+v, Check: %t\n", bob, Check(bob))
// => User: {Name:Bob Email:bob email}, Check: false
}
예뻐 보여요.
Reference
이 문제에 관하여(구조체에서 기본형을 배제하다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/fuuki/articles/20201231-go-exclude-basic-type텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)