WebHU - Programozási kérdések és válaszok

GO: modell (vagy interfész) funkció különböző típusú bemenetekkel

Jelenleg van egy kis alkalmazásom a statisztikák kiszámításához párhuzamos algoritmusokkal. Most problémám van a funkcionalitás egy részének bővítésével. Megpróbálom röviden elmagyarázni. Az alkalmazás a revel keretrendszerre épül. A „stat” vezérlő egyik művelete a bejövő POST json fájlt veszi igénybe. Elemzi. És két csatornát (gorutint) generál a feladatokhoz és az eredményekhez. Mindez úgy működik, mint egy varázslat. De vannak gondjaim a modellekkel. Kódot írtam, hogy lineárisan bővíthessem a modellek mennyiségét, de jelenleg csak egy volt munkában.

És nem minden módszert alkalmaznak ehhez a bővítéshez.

A kód egy részében ez van:

for t := range in {
        for sourceName, charts := range t.Request.Charts {

            var cacheData []byte
            var deserializedData models.StatModel

            //determine the model type
            switch sourceName {
            case "noagg":
                deserializedData = new(models.NoaggModel)
            case "acsi":
                deserializedData = new(models.AcsiModel)
            }

            cache_err := cache.Get(string(string(sourceName) + "_" + string(t.Date)), &cacheData);
            if cache_err != nil {
                panic("the cache is empty")
            }

            marshal_error := json.Unmarshal([]byte(cacheData), &deserializedData)
            if marshal_error == nil {

            }

            deserializedData.FilterData(t.Request.Filters)

            deserializedData.ClusterData(t.Request.Filters)

            w := Work{}
            for _, chart := range charts {
                countedData := ChartElements{}

                if marshal_error == nil {
                    countedData = deserializedData.CountDataForChart(string(chart.Name))
                }else {
                    panic("some is bad")
                }

                w.Name, w.Data = chart.Name, countedData
                out <- w
            }
        }
    }

A Noagg modell és az Asci modell a "stat" modell ugyanazt a felületét valósítja meg:

type StatModel interface {
    FilterData(Filter)
    ClusterData(Filter)
    CountDataForChart(string)[]ChartElement
    GroupByTreeGroups(Filter)[]OrgPack
}

De most hozzá kell adnom néhány új modellt ugyanazzal a felülettel, de van kód, amit nem tudok bővíteni. nem emlékszem hogyan kell ezt csinálni..

func statCount(model NoaggRow, f func(NoaggRow) float64) float64 {
    countedStat := f(model)
    return countedStat
}

func Count(model NoaggRow, name string) float64{

    m := map[string]func(NoaggRow) float64 {
        "HOLD" : HOLD,
        "INB"  : INB,
        "AHT"  : AHT,
        "RING" : RING,
        "TALK" : TALK,
        "ACW"  : ACW,
        "OCC"  : OCC,
    }
    countedStat := statCount(model, m[name])
    return countedStat
}

Ugyanazok a módszerek, mint az ASCI modellhez. AcsiRow-hoz NoaggRow helyett. Hogyan lehet ezt a bemeneti paramétertípust dinamikussá tenni, vagy hogyan lehet a módszereket közössé tenni az összes modellhez. Csak a "map[string]func(......Row)" tömbje és neve különbözik ezen a helyen. Valaki tud nekem ebben segíteni?

21.04.2016

Válaszok:


1

Ha a térkép funkcióinak (azaz HOLD(), INB() stb.) nincs szükségük több hozzáférésre a modellekhez, mint amennyit a StatModel interfész biztosít, akkor a követelményt úgy kell megvalósítani, hogy ezeket a függvényeket módosítsa, hogy a NoaggRow helyett StatModelt kapjon:

func HOLD(s StatModel) float64 {
    ...
}

Ekkor a hozzáadni kívánt AcsiRow függvények ugyanazzal az aláírással rendelkezhetnek, és a statCount és a Count a következőképpen írhatók át:

func statCount(model StatModel, f func(StatModel) float64) float64 {
    countedStat := f(model)
    return countedStat
}

func Count(model StatModel, name string) float64 {
    m := map[string]func(StatModel) float64 {
        "HOLD" : HOLD,
        "INB"  : INB,
        "AHT"  : AHT,
        "RING" : RING,
        "TALK" : TALK,
        "ACW"  : ACW,
        "OCC"  : OCC,
        // Map AcsiModel functions here, let's call them ACSIn here
        // (you mentioned that the names would be different, so
        // I assume they don't get in the way of the functions
        // above):
        "ACSI1": ACSI1,
        "ACSI2": ACSI2,
        "ACSI3": ACSI3,
    }
    countedStat := statCount(model, m[name])
    return countedStat
}

Jogi nyilatkozat: Ez csak egy ötlet, amely azon alapul, amit a bejegyzésben látok. Semmit sem tudok Revelről, és így talán kihagytam néhány olyan fontos részletet, amelyet a Revel-kontextus indukált, és amely megakadályozná ennek a megközelítésnek a megvalósítását.

Frissítés a megjegyzés alapján:

Használja a type állításokat, hogy engedélyezze a HOLD, OCC stb. függvényeket a struktúra-specifikus attribútumok eléréséhez, pl. :

func HOLD (s StatModel) float64 {
    noagg, ok := s.(NoaggRow) // typecast from StateModel to NoaggRow
    if !ok {
        // Looks like the caller did not pass a matching model/name pair into Count().
        // Error handling...
    }
    attr := noagg.AttributeSpecificToNoaggRow
    ...
}

Ez futásidőben kockázatosnak tűnhet, de ha a hívó mindig átadja a megfelelő modell/név értékpárokat a Count()-nak (és feltételezem, hogy így van), akkor a típusadásnak biztonságosnak kell lennie.

21.04.2016
  • Sajnos ezek a HOLD, ..., OCC metódusok a noagg modell attribútumaitól, az új metódusok pedig az acsi attribútumoktól függenek. A stat interfész minden modellje ugyanazokkal az attribútumokkal rendelkezik, mint a dátum, id_tree_division stb. De mindegyiknek megvannak a saját attribútumai a konkrét számításokhoz. Tehát az új metódusok csak az új modellekben meglévő attribútumokkal működnének, és a go alkalmazást nem fordítanák le, hacsak meg nem találnám a megoldást. Ha valaki segít, remélem) 21.04.2016
  • Ah oké... Valahogy már úgy éreztem, hogy a válaszom túl könnyű ahhoz, hogy megoldjam a problémádat :-) Szerencsére úgy tűnik, van mód arra, hogy megtedd, amire szükséged van. A válaszomat ennek megfelelően módosítottam. 22.04.2016
  • Nos, lehet, hogy sikerül. Abban reménykedtem, hogy objektum-orientáltabb módszert használok, és minden modellspecifikus függvényt a saját osztályukon belül tartok, de az Ön módszere arra késztet, hogy az összes számítási módszert áthelyezzem a stat modellbe. Reméltem, hogy úgy használom őket, mint a filterData, ClusterData és CountData metódusokkal. Különböző, modellspecifikus logikájuk van, de egy helyről hívom őket. Csak a modell, amihez hívom őket, eltérhet. Az első kódpéldámban van egy kód: deserializedData.CountDataForChart(string(chart.Name)) . Ezt a metódusokat az nsme karakterlánccal hívja meg, az adott modellből. 22.04.2016
  • Szerintem az OOP megközelítés a Go-ban is lehetséges, csak az öröklődési rész nélkül. Az interfészek határozzák meg a közös viselkedést, és a struktúrák az interfész speciális megvalósításait biztosíthatják. Nehéz elmagyarázni egy megjegyzésben, talán ez a játszótéri kód tisztázza, amit mondani akartam... play.golang. org/p/DnVsE9keuD 22.04.2016
  • Néhány pontosítás hozzáadva, néhány elírás javítva: play.golang.org/p/A4A_QmeKRS 22.04.2016
  • Tehát azt javasolja, hogy hozzon létre egy felületet a NoaggRow && AcsiRow számára (az én esetemben), m.b. StatRow , és adjon hozzá ehhez az új sorinterfészhez az adatok számlálására szolgáló metódusokat, és implementálja ezeket a módszereket minden sormodellben. Ha nem tévedek, akkor a noagg metódus chartCount lehet, hogy nem is módosul. Igen || nem ? 22.04.2016
  • Hibát követtem el, a metódust meg kell változtatni, mert ennek (vagy nekik) interfészt kell implementálnia, és így a modellhez kell kötni. Tehát megpróbálom nem paraméterként küldeni az adatokat, hanem olyan modellből használni, amelyik számlálást kért 22.04.2016
  • A fő probléma megoldva. Nagyon köszönöm! Eszembe jutott, hogyan éljek újra a Go-val) 22.04.2016
  • Nagy! Jó hallani, hogy sikerült megtalálnia ennek a megvalósításának módját. 22.04.2016
  • köszönet a támogatásodért. A golang nem a fő nyelv a szerverek ökoszisztémájában, de nagyon szeretem. Remélem hamarosan az itt található összes fontos funkcionális elem átkerül a Go mikroszolgáltatásaiba)) 22.04.2016
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..