[英]Getting pointer to struct in list in Go
我正在嘗試創建一個函數,它將查看電梯結構的列表(類型容器/列表)並返回指向具有正確IP地址的電梯的指針(該程序用於控制多台計算機上的電梯)如果沒有帶此地址的電梯,則為零。
這是功能代碼:
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
}
我認為第一個返回行中的轉換看起來有點可疑,但它是少數幾個沒有引起編譯器錯誤的實現之一。 當我運行程序時,我首先從其他函數獲取輸出,並且當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
該怎么做? 我已多次重寫該功能,我認為這是使用c.Value.(elevator)
和/或c.Value.(*elevator)
導致問題。 以下是elevator
和Elevator_list
的結構:
type elevator struct {
Ip string
OrderList [FLOORS][3]int32
Floor int32
Dir int
Ms_since_ping int32
}
type ElevatorList struct {
Elevators *list.List
}
elevator
被添加到具有該功能的列表中
func (e *ElevatorList) AddToList(newElevator *elevator){
e.Elevators.PushBack(&newElevator)
}
顯然容器/列表有效,但答案是“應該怎么做?” 可能是“不要使用容器/列表,只需使用普通切片”。 這是另一個版本:
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)
}
}
請注意,ElevatorList不需要是struct。 我完全拋棄了AddToList方法。 你甚至可能會拋出IPIsInList。 沒有它,PrintOne的方法看起來就不復雜了。
func (list ElevatorList) PrintOne(ip string) {
for _, e := range list {
if e.Ip == ip {
fmt.Println("found:", *e)
}
}
fmt.Println(ip, "not found")
}
在你的添加功能中,你需要一個*電梯並在將它放入你的列表之前獲取指針的地址。 在您的檢索功能中,您斷言該類型是電梯兩次。 一旦進入if語句,一次進入返回。 他們倆都不同意真實的類型( *電梯)。 你的if語句是第一個,所以它恐慌地解釋變量是**電梯而不是電梯:
panic: interface conversion: interface is **main.elevator, not main.elevator
我會做兩件事。 首先,將*電梯添加到列表中,而不是**電梯:
func (e *ElevatorList) AddToList(newElevator *elevator){
e.Elevators.PushBack(newElevator)
}
接下來,我將更改if語句,以便它對*電梯進行類型斷言,而不是電梯:
if(*(c.Value.(*elevator)).Ip == ip){
例如,
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)
}
}
輸出:
{192.168.0.10}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.