GORMで使用できる独自のデータ型をユーザ自身で定義できるようにするために、GORMにはいくつかのインターフェースが用意されています。json  を例として参照してみるとよいでしょう。
独自のデータ型を実装する Scanner / Valuer 独自のデータ型を使用するためには、Scanner  と Valuer  インターフェイスを実装する必要があります。これらのインターフェイスを実装することで、DBからの値の取得処理やDBへの保存処理をGORMが行うことが可能になります。
例:
type  JSON json.RawMessagefunc  (j *JSON)   Scan(value interface {}) error  {  bytes, ok := value.([]byte )   if  !ok {     return  errors.New(fmt.Sprint("Failed to unmarshal JSONB value:" , value))   }   result := json.RawMessage{}   err := json.Unmarshal(bytes, &result)   *j = JSON(result)   return  err } func  (j JSON)   Value() (driver.Value, error ) {  if  len (j) == 0  {     return  nil , nil    }   return  json.RawMessage(j).MarshalJSON() } 
 
多くのサードパーティ製パッケージが Scanner/Valuer インターフェイスを実装しており、それらはGORMと併用することができます。例:
import  (  "github.com/google/uuid"    "github.com/lib/pq"  ) type  Post struct  {  ID     uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"`    Title  string    Tags   pq.StringArray `gorm:"type:text[]"`  } 
 
GormDataTypeInterface GORMはカラムのデータ型を type tag  から読み取ります。タグが指定されていない場合は、GormDBDataTypeInterface か GormDataTypeInterface が実装されているかをチェックします。インターフェイスが実装されている場合は、インターフェイスのメソッドの結果をデータ型として使用します。
type  GormDataTypeInterface interface  {  GormDataType() string  } type  GormDBDataTypeInterface interface  {  GormDBDataType(*gorm.DB, *schema.Field) string  } 
 
GormDataType メソッドの返却値は通常のデータ型として使用され、schema.Field の DataType からも取得できます。これは プラグインを作成する  際や hooksを利用する  際に役立ちます。例:
func  (JSON)   GormDataType() string  {  return  "json"  } type  User struct  {  Attrs JSON } func  (user User)   BeforeCreate(tx *gorm.DB) {  field := tx.Statement.Schema.LookUpField("Attrs" )   if  field.DataType == "json"  {        } } 
 
GormDBDataType は通常、マイグレーション時に使用しているドライバに適切なデータ型を返します。例:
func  (JSON)   GormDBDataType(db *gorm.DB, field *schema.Field) string  {           switch  db.Dialector.Name() {   case  "mysql" , "sqlite" :     return  "JSON"    case  "postgres" :     return  "JSONB"    }   return  ""  } 
 
構造体が GormDBDataTypeInterface や GormDataTypeInterface インターフェイスを実装していない場合、GORMはその構造体の一番最初のフィールドからデータ型を推測します。例えば以下の NullString では string がデータ型として使用されます。
type  NullString struct  {  String string     Valid  bool  } type  User struct  {  Name NullString  } 
 
GormValuerInterface GORMは GormValuerInterface インターフェイスを提供しています。これにより、SQL式での作成/更新やコンテキストに基づいた値での作成/更新を行うことができます。例:
type  GormValuerInterface interface  {  GormValue(ctx context.Context, db *gorm.DB) clause.Expr } 
 
SQL Expr での作成/更新 type  Location struct  {    X, Y int  } func  (loc Location)   GormDataType() string  {  return  "geometry"  } func  (loc Location)   GormValue(ctx context.Context, db *gorm.DB) clause.Expr {  return  clause.Expr{     SQL:  "ST_PointFromText(?)" ,     Vars: []interface {}{fmt.Sprintf("POINT(%d %d)" , loc.X, loc.Y)},   } } func  (loc *Location)   Scan(v interface {}) error  {   } type  User struct  {  ID       int    Name     string    Location Location } db.Create(&User{   Name:     "jinzhu" ,   Location: Location{X: 100 , Y: 100 }, }) db.Model(&User{ID: 1 }).Updates(User{   Name:  "jinzhu" ,   Location: Location{X: 100 , Y: 100 }, }) 
 
マップを使用した SQL Expr でレコードを作成/更新することもできます。詳細については、 SQL式/Context Valuer で作成する  および SQL式で更新する  をチェックしてください。
コンテキストに基づく値 現在のコンテキストに基づいて値を作成または更新したい場合は、 GormValuerInterface インターフェイスを実装することで実現可能です。
type  EncryptedString struct  {  Value string  } func  (es EncryptedString)   GormValue(ctx context.Context, db *gorm.DB) (expr clause.Expr) {  if  encryptionKey, ok := ctx.Value("TenantEncryptionKey" ).(string ); ok {     return  clause.Expr{SQL: "?" , Vars: []interface {}{Encrypt(es.Value, encryptionKey)}}   } else  {     db.AddError(errors.New("invalid encryption key" ))   }   return  } 
 
Clause Expression クエリヘルパーを構築したい場合、clause.Expression インターフェイスを実装する構造体を作成することで実現することができます。
type  Expression interface  {    Build(builder Builder) } 
 
詳細については JSON  と SQL Builder  を確認してください。以下は使い方の例です:
db.Find(&user, datatypes.JSONQuery("attributes" ).HasKey("role" )) db.Find(&user, datatypes.JSONQuery("attributes" ).HasKey("orgs" , "orga" )) db.Find(&user, datatypes.JSONQuery("attributes" ).Equals("jinzhu" , "name" )) 
 
独自データ型のコレクション https://github.com/go-gorm/datatypes  のGithubリポジトリに独自データ型のコレクションを用意しています。プルリクエストを歓迎しています!