【问题标题】:Need help understanding `map[String]type` behaviour in Go需要帮助理解 Go 中的 `map[String]type` 行为
【发布时间】:2018-07-05 17:37:34
【问题描述】:

请看一下这段代码:

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.AllDays。 currentWeekContribution.AllDays = append(currentWeekContribution.AllDays, additionalDayContribution) 是 appends 到当前类型 weekContributions 的 AllDays 属性的一部分。

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

我的目标 - 将 dayContribution 对象附加到映射 activity.yearContributions 中的值

我认为-

  1. append 函数按预期工作,因为它在每次迭代中附加 1 个成员
  2. 不知何故,currentWeekContribution.addContribution 行 [第 48 行] 仅附加到局部变量 currentWeekContribution 并且不会更新 currentActivity.yearContributions 映射中的相应值

我对@9​​87654336@ 很陌生,我想我没有关注the go way / 这在java 或ruby 中会起作用 我不知道这种行为叫什么,所以不能用谷歌搜索任何相关的东西。

【问题讨论】:

  • @halfer 更新

标签: oop pointers go reference


【解决方案1】:

有两种方法可以做到这一点。

一,您需要使用指针作为映射值。因此,当您添加本地变量时,您会通过引用进行更改。

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

type dayContributions struct {
    Date         time.Time
    Contribution int
}

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

二、当你在做following时

currentWeekContribution := currentActivity.yearContributions[stringWeekday]

您正在分配一个局部变量。而你正在附加它。现在,您需要重新分配该局部变量。喜欢

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

【讨论】:

  • 真棒@aerokite.. 谢谢你!
猜你喜欢
  • 2018-06-13
  • 2019-11-03
  • 2016-04-28
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
相关资源
最近更新 更多