Я очень новичок в golang и все еще борюсь со многими вещами.
При реализации пользовательского типа, подобного этому type Date time.Time
, определяющего метод для маршалирования/демаршалирования дат, которые поступают в формате "2006-01-02"
(из файла JSON и из запроса API POST), окончательный способ хранения дат в структуре:
{wall:0 ext:63776764800 loc:<nil>}
Может ли кто-нибудь помочь мне понять, почему этот формат (вместо обычного time.Time
), поскольку пользовательский тип Date
пишется с большой буквы, следовательно, экспортируется?
Вот реализация (ссылка на игровую площадку под кодом):
package main
import (
"encoding/json"
"fmt"
"log"
"time"
)
const sample = `{
"ID": "1",
"ticker": "S30J2",
"issueDate": "2022-01-31",
"maturity": "2023-06-30",
"coupon": 0,
"cashFlow": [
{ "date": "2022-06-30",
"rate": 0,
"amortization": 1,
"residual": 0,
"amount": 50},
{
"date": "2023-06-30",
"rate": 0,
"amortization": 1,
"residual": 0,
"amount": 50}
]
}`
type Date time.Time
func (d Date) MarshalJSON() ([]byte, error) {
return []byte(time.Time(d).Format("2006-1-2")), nil
}
func (d *Date) UnmarshalJSON(b []byte) error {
// Disregard leading and trailing "
t, err := time.Parse("2006-1-2", string(b[1:len(b)-2]))
if err != nil {
return err
}
*d = Date(t)
return nil
}
type Flujo struct {
Date Date
Rate float64
Amort float64
Residual float64
Amount float64
}
type Bond struct {
ID string
Ticker string
IssueDate Date
Maturity Date
Coupon float64
Cashflow []Flujo
}
func main() {
var b Bond
if err := json.Unmarshal([]byte(sample), &b); err != nil {
log.Fatalf("%s", err)
}
fmt.Printf("%+v\n", b.IssueDate)
// I need to wrap it via Format.
fmt.Println("Fecha: ", time.Time(b.IssueDate).Format("2006-01-02"))
}
Вот рабочий пример: https://go.dev/play/p/YddzXA9PQdP
Спасибо за помощь и понимание.
Тип Date
— это новый именованный тип, отличный от time.Time
, и у него нет методов, определенных для time.Time
. Методы маршала/демаршала работают нормально, но семейство функций fmt.Print
использует интерфейс Stringer
, если он существует. Таким образом, если вы объявите:
func (d Date) String() string {
x, _ := d.MarshalJSON()
return string(x)
}
Он будет печатать правильно.
Спасибо Бурак! Я упустил из виду, что Date должен быть снабжен правильными методами для печати (т.е. String()) как time.Time