如何覆盖内置类型

时间:2015-08-12 20:43:27

标签: struct go interface

默认情况下time.Duration2h0m0s等格式打印

但是,我想将其打印为2 Hours2 Hours 1 Min

一种方法是,我可以创建一个新的struct TimeDurationStruct并创建一个String()函数。我在golang playground

中做了同样的事情

工作代码

package main

import (
    "fmt"
    "time"
    "math"
)

type TimeDurationStruct struct {
    t time.Duration
}

func (i *TimeDurationStruct) Set(t time.Duration) {
    i.t = t
}

func (i TimeDurationStruct) String() string {
    duration := i.t

    var dayString, hourMinString string
    var days, hours float64

    totalHours := duration.Hours()
    minutes := math.Mod(duration.Minutes(), 60.0)
    if totalHours < 24.0 {
        hours = totalHours
    } else {
        hours = math.Mod(totalHours, 24.0)
        days = totalHours / 24.0
    }

    if hours == 0 {

    } else if hours < 1 {
        if minutes == 1 {
            hourMinString = "1 Min"
        } else {
            hourMinString = fmt.Sprintf("%g Mins", minutes)
        }
    } else if hours >= 1 && hours < 2 {
        if minutes == 0 {
            hourMinString = "1 Hour"
        } else if minutes == 1 {
            hourMinString = "1 Hour 1 Min"
        } else {
            hourMinString = fmt.Sprintf("1 Hour %g Mins", minutes)
        }
    } else {
        if minutes == 0 {
            hourMinString = fmt.Sprintf("%g Hours", hours)
        } else if minutes == 1 {
            hourMinString = fmt.Sprintf("%g Hours 1 Min", hours)
        } else {
            hourMinString = fmt.Sprintf("%g Hours %g Mins", hours, minutes)
        }
    }

    if days > 0 {
        if days == 1 {
            dayString = "1 Day"
        } else {
            dayString = fmt.Sprintf("%g Days ", days)
        }
    }

    return dayString + hourMinString
}

func main() {
    t := time.Now()
    d := t.Add(2 * time.Hour).Sub(t)
    fmt.Println(d)
    var i TimeDurationStruct
    i.Set(d)
    fmt.Println(i)
}

问题

  1. 可以覆盖time.Duration type而不是结构类型。 E.g

    type TimeDurationStruct time.Duration
    

    我尝试了here,但它不起作用......

  2. 有更好/更简单的方法吗?

1 个答案:

答案 0 :(得分:0)

继续你的问题编辑,是的,你可以在没有结构的情况下实现这个效果。问题是当您使用以下内容定义类型时

type TimeDurationStruct time.Duration

您的新TimeDurationStruct类型不会像使用类型嵌入选项时那样继承time.Duration中的任何方法。您仍然可以访问这些方法,但您需要执行类型转换。因此,应修改String方法的开头,以便阅读以下内容:

func (i TimeDurationStruct) String() string {
    duration := time.Duration(i)
    ...