Golang 代码拾遗

摘要

本文主要记录golang的常用代码片段和特殊的代码写法。

内容

var _ 检测接口中的方法是否被定义

可以在结构体未被使用前,让编译器检查其是否实现了接口所需的所有方法。

代码

// 检查 NokiaPhone 是否实现了 Phone 接口所需的所有方法,两种写法都可以。
var _ Phone = (*NokiaPhone)(nil)
var _ Phone = &NokiaPhone{}


type Phone interface {
    call()
}

type NokiaPhone struct {
}

func (nokiaPhone NokiaPhone) call() {
    fmt.Println("I am Nokia, I can call you!")
}

说明

  1. _ 为了避免变量未使用编译的时候报错
  2. _ 的类型为 NokiaPhone

Gorm 自定义JSON Model

可以将自定义类型以Json编码的方式存入数据库文本类型中。使用ORM时,和普通类型没有区别。

第一种写法

// JSONMap
type JSONMap map[string]string

// Scan Scanner
func (t *JSONMap) Scan(value interface{}) error {
    if value == nil {
        return nil
    }

    v, ok := value.(string)
    if !ok {
        return fmt.Errorf("value is not string, value: %v", value)
    }

    // if empty
    if len(v) == 0 {
        b = "{}"
    }

    return json.Unmarshal([]byte(v), t)
}

// Value Valuer
func (t JSONMap) Value() (driver.Value, error) {
    if t == nil {
        return nil, nil
    }
    bytes, err := json.Marshal(t)
    if err != nil {
        return nil, err
    }
    // return string type
    return string(bytes), nil
}

注意: 在Value函数中,如果直接返回bytes,会导致查询时Scan传入的value[]byte类型而报错。

第二种写法

第一种写法中,我们会把数据转换成string存入数据库。但我们发现json函数转换时支持的数据结类型是[]bytes
下面的写法可以避免多余的转换。

// JSONMap
type JSONMap map[string]string

// Scan Scanner
func (t *JSONMap) Scan(value interface{}) error {
    if value == nil {
        return nil
    }

    // empty value
    if reflect.ValueOf(value).Len() == 0 {
        *t = map[string]string{}
        return nil
    }

    return json.Unmarshal(reflect.ValueOf(value).Bytes(), t)
}

// Value Valuer
func (t JSONMap) Value() (driver.Value, error) {
    if t == nil {
        return nil, nil
    }
    return json.Marshal(t)
}

注意:里面空值处理的部分是必须的,如果数据库当时是空值,传入Scanvalue是一个string类型而非[]byte。转义时会出错。

结构体覆盖

可用于Map和结构体的转换,以及复制结构体或Map

func StructCover(in interface{}, to interface{}) error {
    b, err := json.Marshal(&in)
    if err != nil {
        return err
    }

    _ = json.Unmarshal(b, to)
    return nil
}
© 版权声明
THE END
广告
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情

    暂无评论内容