首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Map似乎在递归中删除了值。

Map似乎在递归中删除了值。
EN

Stack Overflow用户
提问于 2019-03-20 17:35:25
回答 1查看 70关注 0票数 1

我一直在研究一个问题,我想我可以用pokemon设置来演示它。我正在读取一个文件,解析该文件并从它们创建对象/结构。这通常不是一个问题,除了现在我需要实现接口,如继承特性。我不希望那里有重复的技能,所以我想我可以用一张地图来复制一个集合的数据结构。然而,在递归parsePokemonFile函数的传递阶段(请参阅implementsComponent情况),我似乎正在失去映射中的值。

我正在使用这样的输入:

4个档案

拉塔塔:

代码语言:javascript
复制
name=Ratatta
skills=Tackle:normal,Scratch:normal

牛头龙:

代码语言:javascript
复制
name=Bulbosaur
implements=Ratatta
skills=VineWhip:leaf

奥迪什:

代码语言:javascript
复制
name=Oddish
implements=Ratatatt
skills=Acid:poison

维诺索:

代码语言:javascript
复制
name=Venosaur
implements=bulbosaur,oddish

我期望下面代码的输出如下所示

代码语言:javascript
复制
Begin!
{Venosaur [{VineWhip leaf} {Acid poison} {Tackle normal} {Scratch normal}]}

但我却得到了

代码语言:javascript
复制
Begin!
{Venosaur [{VineWhip leaf} {Acid poison}]}

我做错了什么?这会是逻辑上的错误吗?或者,我是否在假设地图中包含我不该拥有的值?

代码语言:javascript
复制
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

// In order to create a set of pokemon abilities and for ease of creation and lack of space being taken up
// We create an interfacer capability that imports the skills and attacks from pokemon of their previous evolution
// This reduces the amount of typing of skills we have to do.
// Algorithm is simple. Look for the name "implements=x" and then add x into set.
// Unfortunately it appears that the set is dropping values on transitive implements interfaces

func main() {
     fmt.Println("Begin!")
    dex, err := parsePokemonFile("Venosaur")
    if err != nil {
        fmt.Printf("Got error: %v\n", err)
    }
    fmt.Printf("%v\n", dex)
}

type pokemon struct {
    Name   string
    Skills []skill
}

type skill struct {
    SkillName string
    Type      string
}

func parsePokemonFile(filename string) (pokemon, error) {
    file, err := os.Open(filename)
    if err != nil {
        return pokemon{}, err
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    var builtPokemon pokemon
    for scanner.Scan() {
        component, returned := parseLine(scanner.Text())
        switch component {
        case nameComponent:
            builtPokemon.Name = returned
        case skillsComponent:
            skillsStrings := strings.Split(returned, ",")
            var skillsArr []skill
            // split skills and add them into pokemon skillset
            for _, skillStr := range skillsStrings {
                skillPair := strings.Split(skillStr, ":")
                skillsArr = append(skillsArr, skill{SkillName: skillPair[0], Type: skillPair[1]})
            }
            builtPokemon.Skills = append(builtPokemon.Skills, skillsArr...)
        case implementsComponent:
            implementsArr := strings.Split(returned, ",")
            // create set to remove duplicates
            skillsSet := make(map[*skill]bool)
            for _, val := range implementsArr {
                // recursively call the pokemon files and get full pokemon
                implementedPokemon, err := parsePokemonFile(val)
                if err != nil {
                    return pokemon{}, err
                }
                // sieve out the skills into a set
                for _, skill := range implementedPokemon.Skills {
                    skillsSet[&skill] = true
                }
            }
            // append final set into the currently being built pokemon
            for x := range skillsSet {
                builtPokemon.Skills = append(builtPokemon.Skills, *x)
            }
        }
    }
    return builtPokemon, nil
}

type component int

// components to denote where to put our strings when it comes time to assemble what we've parsed
const (
    nameComponent component = iota
    implementsComponent
    skillsComponent
)

func parseLine(line string) (component, string) {
    arr := strings.Split(line, "=")
    switch arr[0] {
    case "name":
        return nameComponent, arr[1]
    case "implements":
        return implementsComponent, arr[1]
    case "skills":
        return skillsComponent, arr[1]
    default:
        panic("Invalid field found")
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-20 18:31:40

这与Golang地图删除任何值无关。

问题是,您使用的是技能指针的地图,而不是技能。指向相同技能内容的两个指针可能不同。

skillsSet := make(map[*skill]bool)

如果您将此更改为map[skill]bool,则此操作应该有效。你可以试试!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55266979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档