gpt4 book ai didi

go - 数组似乎在 for 循环结束后丢失值

转载 作者:IT王子 更新时间:2023-10-29 02:14:51 24 4
gpt4 key购买 nike

我是初学者(不是一个好的程序员),但我想编写一个小程序,使用 snmp 从交换机转储 mac 地址列表和接口(interface)名称。我使用多个循环将 snmp 值存储到一个结构数组中(此处的代码用于显示行为)。在第一个循环中,我将端口 Vlan id 和 mac 地址存储到结构数组 (var allTableArray [30]allTable) 中。在此循环结束时,我打印数组的内容以确保 mac 地址在数组中。但是当第二个循环开始时(注册桥端口号),数组似乎是空的 (fmt.Printf("deux %x\n",allTableArray[i].macAddr) 和 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)
}

最佳答案

显然是这条线

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

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

如果您尝试做的是更新每个成员的 brPortNb 字段,您可以通过访问该字段并为其分配值而不是分配一个新的 >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 语法,您可以访问索引和值,而无需使用 essai[i] for值(value)。

现在您的两个循环可以变成一个循环,而且没有真正难以理解的嵌入式循环。

我还建议您使用 slice 而不是数组。这样更灵活。

关于go - 数组似乎在 for 循环结束后丢失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36034541/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com