没有泛型的Golang类型断言的解决方案?

时间:2018-05-02 10:37:13

标签: generics go casting type-conversion type-assertion

我使用gorm,它允许使用许多数据类型,例如f["UNIX2STR"] = func(t interface{}, f string) string { switch t.(type) { case int: return time.Unix(int64(t.(int)), 0).Format(f) case uint: return time.Unix(int64(t.(uint)), 0).Format(f) case uint8: return time.Unix(int64(t.(uint8)), 0).Format(f) case *int: return time.Unix(int64(*t.(*int)), 0).Format(f) case *uint: return time.Unix(int64(*t.(*uint)), 0).Format(f) case *uint8: return time.Unix(int64(*t.(*uint8)), 0).Format(f) ..... default: return "" } // return time.Unix(int64(t), 0).Format(f) }

然后我在这个模板中有一个插件:

int64

它将所有整数类型转换为格式化字符串。 那么我想做什么呢?列出所有支持int类型的gorm并将其转换为interface{}

我已经搜索了很多天的解决方案转换<simp>example1</simp><op>example2</op><val>example2</val> 到它的真实类型而没有使用类型断言但是没有工作。

3 个答案:

答案 0 :(得分:1)

我没有使用gorm,但我认为这样的事情可以解决你的问题:

func formatUnix(t interface{}, f string) (string, error) {
    timestampStr := fmt.Sprint(t)
    timestamp, err := strconv.ParseInt(timestampStr, 10, 64)
    if err != nil {
        return "", err
    }
    return time.Unix(timestamp, 0).Format(f), nil
}

不是列出所有可能的类型,而是使用interface{}string转换为fmt.Sprint(),然后使用{{string转换为int64 1}}。

答案 1 :(得分:1)

根据您的评论,听起来您关心的是将任何数字类型转换为字符串。使用fmt.Sprint

可以轻松完成此操作
<?xml version="1.0" encoding="utf-8"?>

<odoo>
    <data noupdate="1">
        <record model="ir.module.category" id="rights_current_weather">
            <field name="name">Weather Info</field> 
            <field name="sequence">2</field>
        </record>

        <record id="rights_current_weather_user" model="res.groups">
            <field name="name">User</field>
            <field name="category_id" ref="rights_current_weather"/>
            <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
        </record>

        <record id="rights_current_weather_manager" model="res.groups">
            <field name="name">Manager</field>
            <field name="category_id" ref="rights_current_weather"/>
            <field name="implied_ids" eval="[(4, ref('rights_current_weather_user'))]"/>
            <field name="users" eval="[(4, ref('base.user_root'))]"/>
        </record>

    </data>
</odoo>

但这与GORM无关。

另一方面,如果您的问题是GORM返回不可预测的类型,只需将您的select语句更改为始终返回一个字符串。例如,对于MySQL,类似于:

stringValue := fmt.Sprint(i) // i is any type

SELECT CAST(someNumberColumn AS VARCHAR) AS stringColumn

答案 2 :(得分:0)

我不认为这是go或gorm的问题。我有点困惑你以多种不同的格式保存你的unix时间戳。顺便说一句,unix时间戳是32位,所以转换(并首先保存)任何8位整数都没有意义。

解决方案是对结构中的所有时间戳使用统一数据类型(int64)。之后,您的格式化函数可以接受int64而不是interface{},而无需任何类型断言。