在循环内追加会重复 Golang 中的最后一个值
Appending inside a loop repeats the last value in Golang
当尝试在 go 中追加迭代的值时,函数将最后一次迭代追加 4 次。例如,我正在尝试将包含网卡数据的字符串解析为映射,并且在迭代时仅附加最后一个:
这是带有代码的 playground link:
https://go.dev/play/p/mKtFvK36PMn
package main
import (
"fmt"
"strings"
)
type Foo struct {
val int
}
func main() {
NetworkJson := "4 NIC(s) Installed.,[01]: Realtek PCIe GbE Family Controller, Connection Name: Ethernet, DHCP Enabled: Yes, DHCP Server: 10.101.10.13, IP address(es), [01]: 10.1.2.62,[02]: VirtualBox Host-Only Ethernet Adapter, Connection Name: VirtualBox Host-Only Network, DHCP Enabled: No, IP address(es), [01]: 192.168.56.1, [02]: fe80::4c17:978a:2c91:8e27,[03]: VMware Virtual Ethernet Adapter for VMnet1, Connection Name: VMware Network Adapter VMnet1, DHCP Enabled: Yes, DHCP Server: 192.168.146.254, IP address(es), [01]: 192.168.146.1, [02]: fe80::88b4:d443:2ab8:59b5,[04]: VMware Virtual Ethernet Adapter for VMnet8, Connection Name: VMware Network Adapter VMnet8, DHCP Enabled: Yes, DHCP Server: 192.168.128.254, IP address(es), [01]: 192.168.128.1, [02]: fe80::a40d:e64:fa9f:e82f"
var IPs []string
var Data []string
var IPMap = make(map[string]string)
var CardMap = make(map[string]interface{})
var CardIP = make(map[string][]map[string]string)
var NetCard = make(map[string][]interface{})
// Faz loop entre as placas de rede
for _, Cards := range strings.Split(string(NetworkJson), ",[") {
// Faz loop entre os dados de cada placa
for _, CardData := range strings.Split(string(Cards), ",") {
// Verifica se dado inicia com espaço em branco
if strings.HasPrefix(CardData, " ") {
// Verifica se dado sem o espaço em branco começa com [
if strings.HasPrefix(strings.TrimSpace(CardData), "[") {
// Pega IPS
IPs = strings.Split(strings.TrimSpace(string(CardData)), ": ")
IPMap[string(IPs[0])] = strings.TrimSpace(string(IPs[1]))
// Se não iniciar com [ verifica se contém :
} else if strings.Contains(CardData, ":") {
// Pega restante dos dados
Data = strings.Split(strings.TrimSpace(string(CardData)), ":")
CardMap[Data[0]] = strings.TrimSpace(Data[1])
}
}
}
if strings.Contains(Cards, "]") {
// Aloca dados
CardMap["Card Name"] = string(strings.SplitN(string(Cards), ",", 2)[0])[5:]
CardIP["IP Adress(es)"] = append(CardIP["IP Adress(es)"], IPMap)
CardMap["IP Adress(es)"] = CardIP["IP Adress(es)"]
CardIP["IP Adress(es)"] = CardIP["IP Adress(es)"][:0]
NetCard["Cards"] = append(NetCard["Cards"], CardMap)
fmt.Println(CardMap)
}
fmt.Println(NetCard["Cards"])
}
}
您正在将所有内容存储到同一个地图变量 CardMap 中,并且您使用的是单一键“Card Name”。 append(NetCard["Cards"], CardMap)
不会执行 CardMap 的 deep 副本,只会附加一个浅表副本,因此每次迭代都会更新浅表副本的数据。你的其他变量也有同样的问题。
将变量声明移动到主循环中:
var NetCard = make(map[string][]interface{})
// Faz loop entre as placas de rede
for _, Cards := range strings.Split(string(NetworkJson), ",[") {
var IPs []string
var Data []string
var IPMap = make(map[string]string)
var CardMap = make(map[string]interface{})
var CardIP = make(map[string][]map[string]string)
// Faz loop entre os dados de cada placa
for _, CardData := range strings.Split(string(Cards), ",") {
// ...
当尝试在 go 中追加迭代的值时,函数将最后一次迭代追加 4 次。例如,我正在尝试将包含网卡数据的字符串解析为映射,并且在迭代时仅附加最后一个:
这是带有代码的 playground link: https://go.dev/play/p/mKtFvK36PMn
package main
import (
"fmt"
"strings"
)
type Foo struct {
val int
}
func main() {
NetworkJson := "4 NIC(s) Installed.,[01]: Realtek PCIe GbE Family Controller, Connection Name: Ethernet, DHCP Enabled: Yes, DHCP Server: 10.101.10.13, IP address(es), [01]: 10.1.2.62,[02]: VirtualBox Host-Only Ethernet Adapter, Connection Name: VirtualBox Host-Only Network, DHCP Enabled: No, IP address(es), [01]: 192.168.56.1, [02]: fe80::4c17:978a:2c91:8e27,[03]: VMware Virtual Ethernet Adapter for VMnet1, Connection Name: VMware Network Adapter VMnet1, DHCP Enabled: Yes, DHCP Server: 192.168.146.254, IP address(es), [01]: 192.168.146.1, [02]: fe80::88b4:d443:2ab8:59b5,[04]: VMware Virtual Ethernet Adapter for VMnet8, Connection Name: VMware Network Adapter VMnet8, DHCP Enabled: Yes, DHCP Server: 192.168.128.254, IP address(es), [01]: 192.168.128.1, [02]: fe80::a40d:e64:fa9f:e82f"
var IPs []string
var Data []string
var IPMap = make(map[string]string)
var CardMap = make(map[string]interface{})
var CardIP = make(map[string][]map[string]string)
var NetCard = make(map[string][]interface{})
// Faz loop entre as placas de rede
for _, Cards := range strings.Split(string(NetworkJson), ",[") {
// Faz loop entre os dados de cada placa
for _, CardData := range strings.Split(string(Cards), ",") {
// Verifica se dado inicia com espaço em branco
if strings.HasPrefix(CardData, " ") {
// Verifica se dado sem o espaço em branco começa com [
if strings.HasPrefix(strings.TrimSpace(CardData), "[") {
// Pega IPS
IPs = strings.Split(strings.TrimSpace(string(CardData)), ": ")
IPMap[string(IPs[0])] = strings.TrimSpace(string(IPs[1]))
// Se não iniciar com [ verifica se contém :
} else if strings.Contains(CardData, ":") {
// Pega restante dos dados
Data = strings.Split(strings.TrimSpace(string(CardData)), ":")
CardMap[Data[0]] = strings.TrimSpace(Data[1])
}
}
}
if strings.Contains(Cards, "]") {
// Aloca dados
CardMap["Card Name"] = string(strings.SplitN(string(Cards), ",", 2)[0])[5:]
CardIP["IP Adress(es)"] = append(CardIP["IP Adress(es)"], IPMap)
CardMap["IP Adress(es)"] = CardIP["IP Adress(es)"]
CardIP["IP Adress(es)"] = CardIP["IP Adress(es)"][:0]
NetCard["Cards"] = append(NetCard["Cards"], CardMap)
fmt.Println(CardMap)
}
fmt.Println(NetCard["Cards"])
}
}
您正在将所有内容存储到同一个地图变量 CardMap 中,并且您使用的是单一键“Card Name”。 append(NetCard["Cards"], CardMap)
不会执行 CardMap 的 deep 副本,只会附加一个浅表副本,因此每次迭代都会更新浅表副本的数据。你的其他变量也有同样的问题。
将变量声明移动到主循环中:
var NetCard = make(map[string][]interface{})
// Faz loop entre as placas de rede
for _, Cards := range strings.Split(string(NetworkJson), ",[") {
var IPs []string
var Data []string
var IPMap = make(map[string]string)
var CardMap = make(map[string]interface{})
var CardIP = make(map[string][]map[string]string)
// Faz loop entre os dados de cada placa
for _, CardData := range strings.Split(string(Cards), ",") {
// ...