需要帮助理解Go中的`map [String] type`行为

时间:2018-01-26 11:22:07

标签: oop pointers go reference

请看一下这段代码:

package activity

import (
    "fmt"
    "strconv"
    "time"
)

type Activity struct {
    yearContributions map[string]weekContributions
}

type dayContributions struct {
    Date         time.Time
    Contribution int
}

type weekContributions struct {
    Notation string
    AllDays  []dayContributions
}

func (currentWeekContribution *weekContributions) addContribution(additionalDayContribution dayContributions) {
    currentWeekContribution.AllDays = append(currentWeekContribution.AllDays, additionalDayContribution)
}

func (currentActivity *Activity) restore() {
    currentActivity.yearContributions = map[string]weekContributions{
        "Sunday":    weekContributions{Notation: "S", AllDays: make([]dayContributions, 0)},
        "Monday":    weekContributions{Notation: "M", AllDays: make([]dayContributions, 0)},
        "Tuesday":   weekContributions{Notation: "T", AllDays: make([]dayContributions, 0)},
        "Wednesday": weekContributions{Notation: "W", AllDays: make([]dayContributions, 0)},
        "Thursday":  weekContributions{Notation: "T", AllDays: make([]dayContributions, 0)},
        "Friday":    weekContributions{Notation: "F", AllDays: make([]dayContributions, 0)},
        "Saturday":  weekContributions{Notation: "S", AllDays: make([]dayContributions, 0)},
    }
}

func (currentActivity *Activity) Recalibrate() {
    currentActivity.restore()

    endDate := time.Now().UTC()
    startDate := endDate.AddDate(-1, 0, 0)

    for d := startDate; endDate.After(d); d = d.AddDate(0, 0, 1) {
        stringWeekday := d.Weekday().String()
        currentWeekContribution := currentActivity.yearContributions[stringWeekday]
        currentWeekContribution.addContribution(dayContributions{Date: d, Contribution: 1})
        fmt.Println(currentWeekContribution) // prints : {T [{2017-01-26 09:39:45.711238257 +0000 UTC 1}]}
    }
    fmt.Println(currentActivity.yearContributions) // prints : map[Tuesday:{T []} Wednesday:{W []} Thursday:{T []} Friday:{F []} Saturday:{S []} Sunday:{S []} Monday:{M []}]
}

func (singleDayContribution dayContributions) ReadableDate() string {
    singleDate := singleDayContribution.Date
    return singleDate.Month().String() + " " + strconv.Itoa(singleDate.Day()) + ", " + strconv.Itoa(singleDate.Year())
}

func (currentActivity Activity) GetContributionsForYear() map[string]weekContributions {
    return currentActivity.yearContributions
}

我正在尝试将新dayContributions附加到数组weekContributions.AllDayscurrentWeekContribution.AllDays = append(currentWeekContribution.AllDays, additionalDayContribution)是当前类型appends的{​​{1}}属性的AllDays部分。

print语句打印weekContributions数组,其中包含数组中的单个成员。但是以下打印函数表示所有地图值,即weekContributions个对象都将空数组作为weekContributions属性。

我的目标 - 将AllDays个对象附加到地图dayContribution

中的值

我认为 -

  1. 追加功能按预期工作,因为它在每次迭代时追加1个成员
  2. 不知何故,activity.yearContributions行[第48行]仅附加到局部变量currentWeekContribution.addContribution,并且不会更新currentWeekContribution地图
  3. 中的相应值

    我是currentActivity.yearContributions的新手,我认为我没有关注golang /这会在the go wayjava中发挥作用 我不知道这种行为是什么,所以不能谷歌搜索任何相关的东西。

1 个答案:

答案 0 :(得分:1)

你可以采取两种方式。

一,你需要将指针用作Map值。因此,当您附加在本地变量中时,您将通过引用进行更改。

type Activity struct {
    yearContributions map[string]*weekContributions
}

type dayContributions struct {
    Date         time.Time
    Contribution int
}

type weekContributions struct {
    Notation string
    AllDays  []*dayContributions
}

二,当你做以下时

currentWeekContribution := currentActivity.yearContributions[stringWeekday]

您正在分配一个局部变量。你正在追求它。现在,您需要重新分配该局部变量。像

currentWeekContribution := currentActivity.yearContributions[stringWeekday]
currentWeekContribution.addContribution(dayContributions{Date: d, Contribution: 1})
currentActivity.yearContributions[stringWeekday]= currentWeekContribution
相关问题