Почему строка map [time.Time] иногда не работает? - PullRequest
0 голосов
/ 11 января 2019

Это пример для отображения, когда строка map [time.Time] "не работает".

package main

import (
    "fmt"
    "time"
)

type MyDate time.Time

func NewMyDate(year, month, day int, tz time.Location) (MyDate, error) {
    return MyDate(time.Date(year, time.Month(month), day, 0, 0, 0, 0, &tz)), nil
}

func (md MyDate)ToTime() time.Time {
    return time.Time(md)
}

func main()  {
    timeMap := make(map[time.Time]string)

    md1, _ := NewMyDate(2019, 1, 1, *time.UTC)
    md2, _ := NewMyDate(2019, 1, 1, *time.UTC)

    timeMap[md1.ToTime()] = "1"
    timeMap[md2.ToTime()] = "2"

    for k, v := range timeMap {
        fmt.Println(k, v)
    }
}

Выход:

2019-01-01 00:00:00 +0000 UTC 1

2019-01-01 00:00:00 +0000 UTC 2

Ответы [ 3 ]

0 голосов
/ 11 января 2019
func NewMyDate(year, month, day int, tz time.Location) (MyDate, error) {
  return MyDate(time.Date(year, time.Month(month), day, 0, 0, 0, 0, &tz)), nil
}

&tz относится к адресу параметра NewMyDate, который может отличаться для каждого вызова. В Go аргументы функции передаются по значению.

Используйте один и тот же часовой пояс для каждого звонка. Например,

package main

import (
    "fmt"
    "time"
)

type MyDate time.Time

func NewMyDate(year, month, day int, tz *time.Location) (MyDate, error) {
    return MyDate(time.Date(year, time.Month(month), day, 0, 0, 0, 0, tz)), nil
}

func (md MyDate) ToTime() time.Time {
    return time.Time(md)
}

func main() {
    timeMap := make(map[time.Time]string)

    md1, _ := NewMyDate(2019, 1, 1, time.UTC)
    md2, _ := NewMyDate(2019, 1, 1, time.UTC)

    timeMap[md1.ToTime()] = "1"
    timeMap[md2.ToTime()] = "2"

    for k, v := range timeMap {
        fmt.Println(k, v)
    }
}

Детская площадка: https://play.golang.org/p/M10Xn4jsoKS

Выход:

2019-01-01 00:00:00 +0000 UTC 2
0 голосов
/ 11 января 2019

Карта работает, как и ожидалось, однако ваши ключи не равны. Если вы добавите fmt.Println(md1.ToTime() == md2.ToTime()), вы увидите это.

Из документации :

Операторы сравнения == и! = Должны быть полностью определены для операндов типа ключа; таким образом, тип ключа не должен быть функцией, картой или слайсом. Если тип ключа является типом интерфейса, эти операторы сравнения должны быть определены для значений динамического ключа; сбой вызовет панику во время выполнения.

0 голосов
/ 11 января 2019

Ваш указатель часового пояса каждый раз отличается. Исправьте это, указав указатель явно:

func NewMyDate(year, month, day int, tz *time.Location) (MyDate, error) {
    return MyDate(time.Date(year, time.Month(month), day, 0, 0, 0, 0, tz)), nil
}

Детская площадка: https://play.golang.org/p/M10Xn4jsoKS.

...