You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go中如何访问自定义类型的原类型方法?(gqlgen自定义Date标量)

解决gqlgen自定义Date标量调用time.Time方法的问题

在gqlgen框架中自定义基于time.Time的Date标量类型时,编写MarshalGQL方法时遇到编译器错误:date.Format undefined (type Date has no field or method Format)。原因是Go中通过type Date time.Time定义的自定义类型不会自动继承底层time.Time的方法,因此无法直接调用Format。

原代码如下:

package scalars

import (
    "fmt"
    "io"
    "time"
)

type Date time.Time

// UnmarshalGQL implements the graphql.Unmarshaler interface
func (date *Date) UnmarshalGQL(value interface{}) error {
    dateAsString, ok := value.(string)
    if !ok {
        return fmt.Errorf("date must be a string")
    }

    parsedTime, err := time.Parse(time.RFC3339, dateAsString)
    if err != nil {
        return fmt.Errorf("failed to convert given date value (%s) to Time struct", dateAsString)
    }
    *date = Date(parsedTime)
    return nil
}

// MarshalGQL implements the graphql.Marshaler interface
func (date Date) MarshalGQL(w io.Writer) {
    // This line causes a compiler error
    w.Write(date.Format(time.RFC3339))
}

解决方法

将自定义的Date类型显式转换为time.Time类型,即可调用其Format方法。另外需要注意:

  • io.Writer.Write接收的参数是[]byte类型,需要将Format返回的字符串转换为字节切片
  • GraphQL的字符串类型需要用双引号包裹,因此要在格式化后的日期前后添加引号

修改后的MarshalGQL方法如下:

// MarshalGQL implements the graphql.Marshaler interface
func (date Date) MarshalGQL(w io.Writer) {
    // 将Date转换为time.Time,调用Format方法,添加引号后转为字节切片写入
    formatted := fmt.Sprintf(`"%s"`, time.Time(date).Format(time.RFC3339))
    w.Write([]byte(formatted))
}

完整代码

package scalars

import (
    "fmt"
    "io"
    "time"
)

type Date time.Time

// UnmarshalGQL implements the graphql.Unmarshaler interface
func (date *Date) UnmarshalGQL(value interface{}) error {
    dateAsString, ok := value.(string)
    if !ok {
        return fmt.Errorf("date must be a string")
    }

    parsedTime, err := time.Parse(time.RFC3339, dateAsString)
    if err != nil {
        return fmt.Errorf("failed to convert given date value (%s) to Time struct", dateAsString)
    }
    *date = Date(parsedTime)
    return nil
}

// MarshalGQL implements the graphql.Marshaler interface
func (date Date) MarshalGQL(w io.Writer) {
    formatted := fmt.Sprintf(`"%s"`, time.Time(date).Format(time.RFC3339))
    w.Write([]byte(formatted))
}

内容的提问来源于stack exchange,提问作者Francis Bartkowiak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:45:35