繁体   English   中英

将 time.Time 作为参数传递给通用 function

[英]Passing time.Time as parameter to generic function

尝试将 generics 与time.Time一起使用。 总体目标是接受time.Time或毫秒作为int64

此代码返回错误:

不能使用“at”(类型 T)作为类型 time.Time

type SomeTime struct {
    At        time.Time
}

func PointFactory[T time.Time](at T) *SomeTime {
    return &SomeTime{
        At:        at,
    }
}

是否可以将time.Time作为参数传递给通用 function? 谢谢

您可以获得的最接近的是将您的 T 参数转换为 any 然后使用类型开关来制作所需的结构:

package main

import (
    "fmt"
    "time"
)

type SomeTime struct {
    At time.Time
}

func PointFactory[T time.Time | int64](at T) *SomeTime {
    v := any(at)
    switch v.(type) {
    case time.Time:
        fmt.Println("time")
        return &SomeTime{
            At: v.(time.Time),
        }

    case int64:
        fmt.Println("int")
        return &SomeTime{
            At: time.Unix(v.(int64), 0),
        }

    }
    return nil

}

func main() {
    fmt.Println(PointFactory(int64(6)))
    fmt.Println(PointFactory(time.Now()))
}

操场

Output:

int
&{1970-01-01 00:00:06 +0000 UTC}
time
&{2009-11-10 23:00:00 +0000 UTC m=+0.000000001}

这是因为 Go 团队的决定:

在此设计的早期版本中,我们允许在类型为类型参数或类型基于类型参数的变量上使用类型断言和类型切换。 我们删除了这个工具,因为总是可以将任何类型的值转换为空接口类型,然后在其上使用类型断言或类型开关。 此外,有时令人困惑的是,在具有使用近似元素的类型集的约束中,类型断言或类型切换将使用实际类型参数,而不是类型参数的基础类型(差异在关于识别的部分中解释匹配的预声明类型)

您可以这样声明多种类型:

func say[T string | int](msg T) {
    fmt.Println(msg)
}

func main() {
    say(1)
    say("hello")
}

游乐场

现在根据您的问题,您可以重新定义您的功能吗? 您可以使用:

PointFromInt(n int) *SomeTime {...}
PointFromTime(t time.Time) *SomeTime {...}

您的用例可能不适合 generics。 或者常规类型的 function 可能会做得更好。

package main import ( "fmt" "time" ) func main() { fmt.Printf("%v\n", PointFactory(time.Now()).At) fmt.Printf("%v\n", PointFactory(time.Now().Unix()).At) } type SomeTime[T time.Time | int64] struct { At T } func PointFactory[T time.Time | int64](at T) *SomeTime[T] { return &SomeTime[T]{ At: at, } }

如果Sometime结构预计接受time.Timeint64则需要声明它,方法将值设置为At what type is available

type SomeTime[T time.Time | int64] struct {
    At T
}

func PointFactoryTime(at time.Time) *SomeTime[time.Time] {
    return &SomeTime[time.Time]{
        At: at,
    }
}

func PointFactoryInt64(at int64) *SomeTime[int64] {
    return &SomeTime[int64]{
        At: at,
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM