douzhong8856 2018-01-26 11:22
浏览 4
已采纳

需要帮助来了解Go中的map_String类型的行为

Please have a look at this code:

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
}

I am trying to append new dayContributions to the array weekContributions.AllDays. currentWeekContribution.AllDays = append(currentWeekContribution.AllDays, additionalDayContribution) is the part appends to the AllDays property of the current type weekContributions.

The print statement prints the weekContributions array with a single member in the array. But the following print function says that all map values i.e. weekContributions objects have empty arrays as AllDays property.

My aim - To append dayContribution objects to values in map activity.yearContributions

I think -

  1. The append function is working as intended as it appends 1 member on each iteration
  2. Somehow, the currentWeekContribution.addContribution line [Line 48] is only appending to the local variable currentWeekContribution and doesn't update the corresponding value in currentActivity.yearContributions map

I am very new to golang and I think I am not following the go way / this would have worked in java or ruby I don't know what this behaviour is called, so can't google search anything relevant.

  • 写回答

1条回答 默认 最新

  • douke1905 2018-01-26 11:26
    关注

    Two way you can do this.

    One, You need to use pointer in as Map value. So that when you are appending in your local variable, you are changing through reference.

    type Activity struct {
        yearContributions map[string]*weekContributions
    }
    
    type dayContributions struct {
        Date         time.Time
        Contribution int
    }
    
    type weekContributions struct {
        Notation string
        AllDays  []*dayContributions
    }
    

    Two, When you are doing following

    currentWeekContribution := currentActivity.yearContributions[stringWeekday]
    

    You are assigning a local variable. And you are appending to it. Now, you need to reassign that local variable. Like

    currentWeekContribution := currentActivity.yearContributions[stringWeekday]
    currentWeekContribution.addContribution(dayContributions{Date: d, Contribution: 1})
    currentActivity.yearContributions[stringWeekday]= currentWeekContribution
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥100 已有python代码,要求做成可执行程序,程序设计内容不多
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助
  • ¥15 STM32控制MAX7219问题求解答