# ロールを型で表現する
```go
package main
import (
"fmt"
"reflect"
)
// Define a struct
type User struct {
Name string
Email string
Roles []string
}
// Use the struct as an embedded field
type Admin struct {
User
}
// Define an interface
type Subject interface {
String() string
}
// Implement the interface for User
func (u User) String() string {
return fmt.Sprintf("%s <%s>", u.Name, u.Email)
}
// Use the interface
func Stringify(sub Subject) string {
return sub.String()
}
func TypeSwitch(sub Subject) {
switch sub.(type) {
case User:
fmt.Println("sub is a User")
case Admin:
fmt.Println("sub is an Admin")
}
}
func main() {
user := User{
Name: "John Doe",
Email: "
[email protected]",
Roles: []string{"user"},
}
admin := Admin{
User: User{
Name: "Bob Smith",
Email: "
[email protected]",
Roles: []string{"admin", "user"},
},
}
fmt.Println(Stringify(user)) //=> John Doe <
[email protected]>
fmt.Println(Stringify(admin)) //=> Bob Smith <
[email protected]>
var sub1 Subject
var sub2 Subject
sub1 = user
sub2 = admin
fmt.Println(Stringify(sub1)) //=> John Doe <
[email protected]>
fmt.Println(Stringify(sub2)) //=> Bob Smith <
[email protected]>
fmt.Println(reflect.TypeOf(sub1)) //=> main.User
fmt.Println(reflect.TypeOf(sub2)) //=> main.Admin
// Type assertion
if _, ok := sub1.(User); ok {
fmt.Println("sub1 is a User")
}
if _, ok := sub1.(Admin); ok {
fmt.Println("sub1 is an Admin")
}
// Type switch
TypeSwitch(sub1) //=> sub is a User
TypeSwitch(sub2) //=> sub is an Admin
}
```