1
votes

Pourquoi la chaîne map [time.Time] ne fonctionne pas parfois?

Ceci est un exemple pour montrer quand la chaîne de la carte [time.Time] "ne fonctionne pas".

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)
    }
}

La sortie:

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

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


1 commentaires

Bien que la réponse ci-dessous puisse fonctionner dans ce cas particulier, je suggérerais de ne jamais utiliser time.Time comme clé de carte. time.Time n'est pas comparable de manière fiable pour l'égalité lorsqu'il est généré à partir de l'horloge système, car il contient une valeur d'horloge monotone privée à ajuster pour le biais.


3 Réponses :


2
votes

Votre pointeur de fuseau horaire est différent à chaque fois. Corrigez cela en fournissant explicitement le pointeur:

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
}

Playground: https: / /play.golang.org/p/M10Xn4jsoKS .


0 commentaires

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

& tz fait référence à l'adresse du paramètre NewMyDate , qui peut être différente pour chaque appel. Dans Go, les arguments de fonction sont passés par valeur.

Utilisez le même fuseau horaire pour chaque appel. Par exemple,

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)
    }
}

Playground: https: // play.golang.org/p/M10Xn4jsoKS

Output:

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
}

0 commentaires

0
votes

La carte fonctionne comme prévu, cependant, vos clés ne sont pas égales. Si vous ajoutez fmt.Println (md1.ToTime () == md2.ToTime ()) , vous verrez cela.

Dans la documentation :

Les opérateurs de comparaison == et! = doivent être entièrement définis pour les opérandes de type clé; ainsi, le type de clé ne doit pas être une fonction, une carte ou une tranche. Si le type de clé est un type d'interface, ces opérateurs de comparaison doivent être définis pour les valeurs de clé dynamique; l'échec provoquera une panique à l'exécution.


0 commentaires