简体   繁体   English

在Go中获取列表中的struct指针

[英]Getting pointer to struct in list in Go

I'm trying to make a function that will look through a list (type container/list) of elevator-structs and return a pointer to the elevator that has the correct ip-address (the program is meant to control elevators on multiple computers) or nil if there is no elevator with this address. 我正在尝试创建一个函数,它将查看电梯结构的列表(类型容器/列表)并返回指向具有正确IP地址的电梯的指针(该程序用于控制多台计算机上的电梯)如果没有带此地址的电梯,则为零。

Here is the function code: 这是功能代码:

func (e *ElevatorList)IPIsInList(ip string) *elevator{
    for c := e.Elevators.Front(); c != nil; c = c.Next(){
        if(c.Value.(elevator).Ip == ip){
                return c.Value.(*elevator)
        }
    }
    return nil
}

I think the casting in the first return line looks kind of fishy but it's one of the few implementations that hasn't caused compiler errors. 我认为第一个返回行中的转换看起来有点可疑,但它是少数几个没有引起编译器错误的实现之一。 When I run the program I first get the output from other functions, and when the IPIsInList() function is called i get the following: 当我运行程序时,我首先从其他函数获取输出,并且当IPIsInList()函数时,我得到以下内容:

panic: interface conversion: interface is **main.elevator, not main.elevator

runtime.panic+0xac /home/fredrik/go/src/pkg/runtime/proc.c:1254
runtime.panic(0x4937a8, 0xf84002aaf0)
assertE2Tret+0x11d /home/fredrik/go/src/pkg/runtime/iface.c:312
assertE2Tret(0x4927f8, 0x45e6d8, 0xf8400004f0, 0x7fbae00c1ed8, 0x10, ...)
runtime.assertE2T+0x50 /home/fredrik/go/src/pkg/runtime/iface.c:292
runtime.assertE2T(0x4927f8, 0x45e6d8, 0xf8400004f0, 0x28)
main.(*ElevatorList).IPIsInList+0x5b /home/fredrik/Dropbox/Programmering/go/listtest/elevatorList.go:72
main.(*ElevatorList).IPIsInList(0xf8400001c8, 0x4a806c, 0x2e3332310000000f, 0x0, 0x0, ...)
main.main+0x1f3 /home/fredrik/Dropbox/Programmering/go/listtest/main.go:53
main.main()
runtime.mainstart+0xf /home/fredrik/go/src/pkg/runtime/amd64/asm.s:78
runtime.mainstart()
runtime.goexit /home/fredrik/go/src/pkg/runtime/proc.c:246
runtime.goexit()
----- goroutine created by -----
_rt0_amd64+0xc9 /home/fredrik/go/src/pkg/runtime/amd64/asm.s:65

How should this be done? 该怎么做? I have rewritten the function many times and I think it's the use of c.Value.(elevator) and/or c.Value.(*elevator) that's causing the problem. 我已多次重写该功能,我认为这是使用c.Value.(elevator)和/或c.Value.(*elevator)导致问题。 Here are the structs for elevator and Elevator_list : 以下是elevatorElevator_list的结构:

type elevator struct {
Ip string
OrderList [FLOORS][3]int32
Floor int32
Dir int
Ms_since_ping int32
}

type ElevatorList struct {

Elevators *list.List

}

The elevator s are added to the list with the function elevator被添加到具有该功能的列表中

func (e *ElevatorList) AddToList(newElevator *elevator){
e.Elevators.PushBack(&newElevator)

}

Obviously container/list works, but the answer to "How should this be done?" 显然容器/列表有效,但答案是“应该怎么做?” may be "don't use container/list, just use plain slices." 可能是“不要使用容器/列表,只需使用普通切片”。 Here's an alternative version: 这是另一个版本:

package main

import "fmt"

const FLOORS = 6

type elevator struct {
    Ip            string
    OrderList     [FLOORS][3]int32
    Floor         int32
    Dir           int
    Ms_since_ping int32
}

type ElevatorList []*elevator

func (list ElevatorList) IPIsInList(ip string) *elevator {
    for _, e := range list {
        if e.Ip == ip {
            return e
        }
    }
    return nil
}

func (list ElevatorList) PrintAll() {
    fmt.Println(len(list), "items in list:")
    for _, e := range list {
        fmt.Println("  ", *e)
    }
}

func main() {
    var list ElevatorList
    list = append(list, &elevator{Ip: "1.1.1.1"})
    list = append(list, &elevator{Ip: "2.2.2.2"})
    list.PrintAll()
    list.PrintOne("1.1.1.1")
}

func (list ElevatorList) PrintOne(ip string) {
    if e := list.IPIsInList(ip); e == nil {
        fmt.Println(ip, "not found")
    } else {
        fmt.Println("found:", *e)
    }
}

Note that there was no need for ElevatorList to be a struct. 请注意,ElevatorList不需要是struct。 I completely tossed the AddToList method. 我完全抛弃了AddToList方法。 You might even toss IPIsInList. 你甚至可能会抛出IPIsInList。 Without it the method PrintOne doesn't look any more complex. 没有它,PrintOne的方法看起来就不复杂了。

func (list ElevatorList) PrintOne(ip string) {
    for _, e := range list {
        if e.Ip == ip {
            fmt.Println("found:", *e)
        }
    }
    fmt.Println(ip, "not found")
}

In your add function, you are taking a *elevator and taking the address of the pointer before putting it in your list. 在你的添加功能中,你需要一个*电梯并在将它放入你的列表之前获取指针的地址。 In your retrieve function you are asserting that the type is an elevator twice. 在您的检索功能中,您断言该类型是电梯两次。 Once in the if statement and once in the return. 一旦进入if语句,一次进入返回。 Both of them disagree with the true type ( *elevator). 他们俩都不同意真实的类型( *电梯)。 Your if statement is the first one so it panics explaining that the variable is an **elevator and not an elevator: 你的if语句是第一个,所以它恐慌地解释变量是**电梯而不是电梯:

panic: interface conversion: interface is **main.elevator, not main.elevator

I would do two things. 我会做两件事。 First, add *elevators to the list, not **elevators: 首先,将*电梯添加到列表中,而不是**电梯:

func (e *ElevatorList) AddToList(newElevator *elevator){
    e.Elevators.PushBack(newElevator)
}

Next, I would change the if statement so it does a type assertion to *elevator, not elevator: 接下来,我将更改if语句,以便它对*电梯进行类型断言,而不是电梯:

if(*(c.Value.(*elevator)).Ip == ip){

For example, 例如,

package main

import (
    "container/list"
    "fmt"
)

type Elevator struct {
    Ip string
}

type Elevators struct {
    List *list.List
}

func (e *Elevators) AddToList(elevator *Elevator) {
    e.List.PushBack(elevator)
}

func (e *Elevators) IPIsInList(ip string) *Elevator {
    for c := e.List.Front(); c != nil; c = c.Next() {
        if c.Value.(*Elevator).Ip == ip {
            return c.Value.(*Elevator)
        }
    }
    return nil
}

func main() {
    elevators := Elevators{list.New()}
    ip := "192.168.0.10"
    elevator := Elevator{Ip: ip}
    elevators.AddToList(&elevator)
    eip := elevators.IPIsInList(ip)
    if eip != nil {
        fmt.Println(*eip)
    }
}

Output: 输出:

{192.168.0.10}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取指向列表中元素的指针 - Getting pointer to element in a list 在 go 中创建一个包含列表类型的结构 - Creating a struct that contains list types in go C ++ std ::指向结构的指针列表 - C++ std::list of pointer to a struct 复制指向函数中结构体的指针(链表) - Copy a pointer to a struct in a function (linked list) 如何更新转到列表中的下一个指针? - How to update the next pointer in place in go list? 错误(分段错误核心已转储)- 列表和结构指针 - Error (segmentation fault core dumped) - List and struct pointer 如何使用包含 void 指针和指向结构的递归指针的单链表结构格式在 C 中创建嵌套列表? - How to make a nested list in C using a single linked list struct format which contains a void pointer and a recursive pointer to the struct? 对结构的结构列表进行排序 - Sorting a struct list of struct 尝试将指针复制到列表,出现“无法在初始化时将…转换为…”错误 - Trying to copy the pointer to a list, getting “cannot convert … to … in initialization” error 如何将整数的python列表转换为十六进制列表,得到列表错误“ struct.error:必需的参数不是整数” - How to convert python list of interger to list of hex, getting List error “struct.error: required argument is not an integer”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM