在for循环结束后,数组似乎丢失了值

时间:2016-03-16 11:34:25

标签: go

我是一个初学者(而不是一个优秀的程序员),但我想写一个小程序,它会从交换机转储mac地址列表&接口名称使用snmp。我使用多个循环将snmp值存储到struct数组中(此处的代码用于显示行为)。 在第一个循环中,我存储了Ports Vlan id& mac地址转换为struct数组(var allTableArray [30] allTable)。在这个循环结束时,我打印数组的内容,以确保mac地址在数组中。 但是当第二个循环开始时(注册桥接端口号),该数组似乎为空(fmt.Printf("deux %x\n",allTableArray[i].macAddr) and fmt.Printf("trois %s\n",allTableArray[i].ptVlan1id))

我不明白为什么我的阵列似乎是空的。你有什么想法吗?

package main

import (
    "flag"
    "fmt"
    "os"
    "time"
    "strings"
    "github.com/soniah/gosnmp"
    "math/big"
)

type oidMacAddr struct {
    oid string
    macaddr string
}

type allTable struct {
    ptVlan1id string
    macAddr []byte
    brPortNb *big.Int
    ifIndex *big.Int
    ifName string
}

var macAddrTable [30]oidMacAddr


func main() {
    flag.Parse()

    if len(flag.Args()) < 1 {
            flag.Usage()
            os.Exit(1)
    }
    target := flag.Args()[0]
    showMacAddrTable(target)
}

func printValue(pdu gosnmp.SnmpPDU) error {
    fmt.Printf("%s = ", pdu.Name)

    //fmt.Println(reflect.TypeOf(pdu.Value.([]byte)))
    switch pdu.Type {
    case gosnmp.OctetString:
            b := pdu.Value.([]byte)
            fmt.Printf("STRING: %x\n", b)
    default:
            fmt.Printf("TYPE %d: %d\n", pdu.Type, gosnmp.ToBigInt(pdu.Value))
    }
    return nil
}


func showMacAddrTable(target string) () {

    var allTableArray [30]allTable
    ptVlan1Oid := ".1.3.6.1.2.1.17.4.3.1.1"
    brPortOid := ".1.3.6.1.2.1.17.4.3.1.2"
    brPortIfIndex := ".1.3.6.1.2.1.17.1.4.1.2"
    ifIndexIfName := ".1.3.6.1.2.1.31.1.1.1.1"
    community := "public"

    gosnmp.Default.Target = target
    gosnmp.Default.Community = community
    gosnmp.Default.Timeout = time.Duration(10 * time.Second) // Timeout better suited to walking
    err := gosnmp.Default.Connect()
    if err != nil {
            fmt.Printf("Connect err: %v\n", err)
            os.Exit(1)
    }

    var essai []gosnmp.SnmpPDU
    essai, err = gosnmp.Default.BulkWalkAll(ptVlan1Oid)
    if err != nil {
            fmt.Printf("Walk Error: %v\n", err)
            os.Exit(1)
    }
    for i :=0 ; i < len(essai); i++ {
            s := strings.TrimPrefix(essai[i].Name, ".1.3.6.1.2.1.17.4.3.1.1")
            fmt.Printf("%s = ", s)
            fmt.Printf("%x\n", essai[i].Value.([]byte))
            bytes := essai[i].Value.([]byte)
            macAddrTable[i] = oidMacAddr {s, string(bytes)}
            allTableArray[i] = allTable {ptVlan1id: s, macAddr: bytes}
            if(allTableArray[i].macAddr != nil){
                    fmt.Printf("%x\n",allTableArray[i].macAddr)
            }


    }
    essai, err = gosnmp.Default.BulkWalkAll(brPortOid)
    if err != nil {
            fmt.Printf("Walk Error: %v\n", err)
            os.Exit(1)
    }
    for i:=0 ; i < len(essai); i++ {
            s := strings.TrimPrefix(essai[i].Name, ".1.3.6.1.2.1.17.4.3.1.2")
            fmt.Printf("%s = ", s)
            fmt.Printf("%d\n", essai[i].Value)
            for j:=0 ; j < len(allTableArray); j++ {
                    if (s == allTableArray[j].ptVlan1id) {
                            allTableArray[j] = allTable {brPortNb: gosnmp.ToBigInt(essai[i].Value) }
                    }
            }
                    fmt.Printf("deux %x\n",allTableArray[i].macAddr)
                    fmt.Printf("trois %s\n",allTableArray[i].ptVlan1id)
    }

    os.Exit(1)
}

1 个答案:

答案 0 :(得分:1)

显然这一行

allTableArray[j] = allTable {brPortNb: gosnmp.ToBigInt(essai[i].Value) }

使用新的allTable实例更新每个成员,其中brPortNb以外的每个字段都未定义,因此变为nil

如果您要尝试更新每个成员的brPortNb字段,您可以通过访问该字段并为其指定值而不是分配新{{} {1}}每个成员

allTable

另外,请尝试简化这样的循环,提供allTableArray[j].brPortNb = gosnmp.ToBigInt(essai[i].Value)

len(essai) == len(allTableArray)

请注意,通过使用for i, v := range essai { s := strings.TrimPrefix(v.Name, ".1.3.6.1.2.1.17.4.3.1.1") bytes := v.Value.([]byte) macAddrTable[i] = oidMacAddr { s, string(bytes) } allTableArray[i] = allTable { ptVlan1id: s, macAddr: bytes } s = strings.TrimPrefix(v.Name, ".1.3.6.1.2.1.17.4.3.1.2") if s == allTableArray[i].ptVlan1id { allTableArray[i].brPortNb = gosnmp.ToBigInt(v.Value) } } 语法,您可以访问索引和值,而无需使用for i, v := range essai作为值。

现在你的两个循环可以只变成一个,加上没有嵌入式循环,这些循环真的很难理解。

我还建议您使用切片而不是数组。它更灵活。