【问题标题】:Custom golang sql.NullString Stringer Interface自定义 golang sql.NullString Stringer 接口
【发布时间】:2021-01-04 07:27:49
【问题描述】:

我想为所有实例 sql.NullString 覆盖 Stringer 接口,以便实例的输出为 instance.String 而不是 { instance.String, instance.Valid }

通常的做法是提供一个 Stringer 接口。 使用 sql.NullString,Stringer 接口方法无法编译,因为已经存在 String 字段。

解决方法是在任何地方都使用instance.String

type NullString sql.NullString

// this fails to compile as sql.NullString has a field named String  
func (x *NullString) String() string {
    if !x.Valid {
        x.String = ""
    }
    return x.String
}

如果结构(如 sql.NullString)已经具有 String 字段,如何创建 Stinger 接口?

【问题讨论】:

  • 注意:type NullString sql.NullString“失去”ScanValue 方法,因此 your NullString 的实例将失去其用途。
  • “我想为所有实例 sql.NullString 覆盖 Stringer 接口”没有意义,因为你不能在 Go 中这样做。您无法覆盖。放弃在 Go 中没有意义的 OOP 术语。
  • @Volker 很高兴改写这个问题。

标签: go


【解决方案1】:

我建议扩展 sql.NullString 并将方法覆盖或添加到扩展类型。

// NS extends sql null string
type NS struct{ sql.NullString }

func (s NS) String() string {
    return s.NullString.String
}

NS 将具有 sql.NullString 的方法以及添加到 NS 本身的方法。

这是playgorund中的示例用法

【讨论】:

    【解决方案2】:
    
    import "database/sql/driver"
    
    type NullString struct { ns sql.NullString }
    
    func (s *NullString) Scan(value interface{}) error {
        return s.ns.Scan(value)
    }
    
    func (s NullString) Value() (driver.Value, error) {
        return s.ns.Value()
    }
    
    func (s NullString) String() string {
        return s.ns.String
    }
    

    【讨论】:

    • 答案是正确的 - 但扩展 sql.Nullstring 避免了重新定义所有现有和未来(以及非覆盖)方法的需要。
    • @chris_f 你将如何扩展 sql.NullString ?
    • @KeithJohnHutchison Go 不支持类型扩展,所以我的猜测是 chris_f 指的是 embedding 类型,就像在 Sarath 的回答中所展示的那样。
    • 正如@mkopriva 指出的那样:您不能扩展现有类型或覆盖其方法,以使更改以透明的方式显示在任何地方。提供一种匿名嵌入sql.NullString 的新类型是我所知道的唯一解脱。在那里,您可以根据需要添加和/或覆盖方法。
    猜你喜欢
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2016-12-15
    • 2018-03-08
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多