Generating more general type of code

I have a program where many functions are similar to each other in different structures, however, I end up writing these functions again and again, because the variable that is processed inside has different structures.

I wrote a sample code here.

On go playgroud

package main

import "fmt"

func (a *Match) Add(v Match) {
    a.Runs += v.Runs
    a.Points += v.Points
}

type Match struct {
    Runs   uint64
    Points uint64
}

func (a *Activity) Add(v Activity) {
    a.Walk += v.Walk
    a.Jog += v.Jog
}

type Activity struct {
    Walk uint64
    Jog  uint64
}

func GetDailyMatches() map[string]Match {
    var dailyMatches map[string]Match

    Match1, Match2 := Match{5, 10}, Match{1, 2}
    dailyMatches = make(map[string]Match)
    dailyMatches["01"] = Match1
    dailyMatches["02"] = Match2
    dailyMatches["03"] = Match1
    dailyMatches["04"] = Match2
    return dailyMatches
}

func GetDailyActivities() map[string]Activity {
    var dailyActivities map[string]Activity

    Activity1, Activity2 := Activity{5, 10}, Activity{1, 2}
    dailyActivities = make(map[string]Activity)
    dailyActivities["01"] = Activity1
    dailyActivities["02"] = Activity2
    dailyActivities["03"] = Activity1
    dailyActivities["04"] = Activity2
    return dailyActivities
}

func main() {
    fmt.Println(CalculateMatchSummary("01", "03"))
    fmt.Println(CalculateActivitySummary("02", "04"))
    fmt.Println(CalculateMatchSummary("01", "03"))
    fmt.Println(CalculateActivitySummary("02", "04"))
}

func CalculateMatchSummary(start, end string) (total Match) {
    dailyMatches := GetDailyMatches()
    for day, value := range dailyMatches {
        if day < start {
            continue
        } else if day > end {
            continue
        } else {
            total.Add(value)
        }
    }
    return
}

func CalculateActivitySummary(start, end string) (total Activity) {
    dailyActivities := GetDailyActivities()
    for day, value := range dailyActivities {
        if day < start {
            continue
        } else if day > end {
            continue
        } else {
            total.Add(value)
        }
    }
    return
}

If you notice that both Matchand Activityhave the same functions and the same structure, except that inside they have a different structure.

Is there an easy way to make the code more general (Go generics, which Go doesn’t have ??) in the Golang itself.

+4
source share
1 answer

Go "". , . : https://play.golang.org/p/bfqZsFOgVQ

:

func AddTwo(a, b interface{}) interface{} {
    va := reflect.ValueOf(a)
    vb := reflect.ValueOf(b)
    res := reflect.New(reflect.TypeOf(a)).Elem()
    if va.Kind() != reflect.Struct && vb.Kind() != reflect.Struct {
        return nil
    }

    na, nb := va.NumField(), vb.NumField()
    if na != nb {
        return nil
    }

    for i := 0; i < na; i++ {
        // additional verification needed here
        fa := va.Field(i).Uint()
        fb := vb.Field(i).Uint()
        fr := fa + fb
        res.Field(i).SetUint(fr)
    }

    return res.Interface()
}

, . uint64, . uint64, !

, , . , , .

EDIT: . "a", .SetUint().

+1

Source: https://habr.com/ru/post/1611964/


All Articles