Golang中如何访问从List获取的元素 [已解决]

Golang中如何访问从List获取的元素 [已解决] 容器/列表在添加结构体时工作正常,但当我检索结构体时无法访问其字段。显然我遗漏了某些东西。代码如下;也可在 https://play.golang.org/p/Zr0YOy9eLtD 查看…

package main

import ("fmt";"container/list";"os")

type testRec struct{ name string; age int }

var d0= testRec {name: "Bill", age: 29}
var d1= testRec {name: "Bob", age: 30}

var list0 *list.List

func main(){
list0=list.New(); list0.Init();

p0:=list0.PushBack(&d0); p1:=list0.PushBack(&d1);

fmt.Println("Items on list: ",list0.Len());
fmt.Println("p0: ",p0,"\np1: ",p1)		// force a reference

// now process a list item
r0:=list0.Front(); fmt.Println("r0: ",r0)		// should match p0
data:=r0.Value; fmt.Println(data);
_,ok:=data.(testRec)
if ok==false {  fmt.Println("Wrong type"); os.Exit(1);}
//fmt.Println("Name: ",v0.name);
fmt.Println("Exit OK")
os.Exit(0);
}

运行结果如下:

bjc@sol2 ~/go5 $ go run test1.go
Items on list:  2
p0:  &{0xc00005a1b0 0xc00005a150 0xc00005a150 0x546410} 
p1:  &{0xc00005a150 0xc00005a180 0xc00005a150 0x546430}
r0:  &{0xc00005a1b0 0xc00005a150 0xc00005a150 0x546410}
&{Bill 29}
Wrong type
exit status 1

那么如何将类型强制转换为我的结构体?(我已经尝试了几种替代方案,但编译器都不接受。)

任何帮助都将不胜感激


更多关于Golang中如何访问从List获取的元素 [已解决]的实战教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

看起来不错。我会测试一下。谢谢

更多关于Golang中如何访问从List获取的元素 [已解决]的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这正是进行类型转换所需要的。

再次感谢

建议添加错误检查

// now process the list items

for e:=list0.Front(); e!=nil; e=e.Next(){
	tr,ok:=e.Value.(*testRec)
	if ok==false{
		fmt.Println("List is corrupt.  Consider restarting the system");
		break;}
	fmt.Println(tr.name,tr.age);
}

你可以访问ElementValue

package main

import (
	"container/list"
	"fmt"
)

type testRec struct {
	name string
	age  int
}

func (tr testRec) String() string {
	return fmt.Sprintf("testRec(name=%v, age=%v)", tr.name, tr.age)
}

var d0 = testRec{name: "Bill", age: 29}
var d1 = testRec{name: "Bob", age: 30}

var list0 *list.List

func main() {
	list0 = list.New()
	list0.Init()

	p0 := list0.PushBack(&d0)
	p1 := list0.PushBack(&d1)

	fmt.Printf("p0: %s\n", p0.Value)
	fmt.Printf("p1: %s\n", p1.Value)
}

输出:

p0: testRec(name=Bill, age=29)
p1: testRec(name=Bob, age=30)

https://play.golang.com/p/cwUvPAVo8DO

我不知道 GetFromElement 应该是什么。

尝试对 Value 进行类型断言

package main

import (
	"container/list"
	"fmt"
)

type testRec struct {
	name string
	age  int
}

func (tr testRec) String() string {
	return fmt.Sprintf("testRec(name=%v, age=%v)", tr.name, tr.age)
}

var d0 = testRec{name: "Bill", age: 29}
var d1 = testRec{name: "Bob", age: 30}

var list0 *list.List

func main() {
	list0 = list.New()
	list0.Init()

	list0.PushBack(&d0)
	list0.PushBack(&d1)

	for e := list0.Front(); e != nil; e = e.Next() {
		tr, ok := e.Value.(*testRec)
		if ok == false {
			fmt.Println("List is corrupt.  Consider restarting the system")
			break
		}
		fmt.Println(tr.name, tr.age)
	}

}

https://play.golang.com/p/UZZA-W1AXYq

感谢Lutz。你的打印程序也能处理从列表中读取的项目。我的问题是我想要将记录放入列表然后再读取出来。我尝试从元素中获取记录。Go playground https://play.golang.org/p/_7PEB2I7nz7。

package main

import ("fmt";"container/list";"os")

type testRec struct{ name string; age int }

 func (tr testRec) String() string {
return fmt.Sprintf("testRec(name=%v, age=%v)", tr.name, tr.age)
}

func (tr testRec) GetFromElement() testRec {
return testRec{name: tr.name, age: tr.age}
}

var d0= testRec {name: "Bill", age: 29}
var d1= testRec {name: "Bob", age: 30}

var list0 *list.List

func main(){
list0=list.New(); list0.Init();

p0:=list0.PushBack(&d0); p1:=list0.PushBack(&d1);

fmt.Println("Items on list: ",list0.Len());

// now process a list item
r0:=list0.Front();
fmt.Printf("r0:p %s\n",r0.Value);
v0:=r0.Value.GetFromElement();
fmt.Println("v0: name: ",v0.name," Age: ",v0.age);
fmt.Println("Exit OK")
os.Exit(0);
}

我遇到了编译时错误

prog.go:31:14: r0.Value.GetFromElement undefined (type interface {} is interface with no methods)

Go build failed.

问题在于你向列表中存储的是结构体指针(&d0&d1),但在类型断言时却尝试断言为值类型 testRec。当你使用 r0.Value 获取元素时,得到的是 *testRec 类型(指针),而不是 testRec 类型。

以下是修正后的代码:

package main

import (
	"container/list"
	"fmt"
)

type testRec struct {
	name string
	age  int
}

var d0 = testRec{name: "Bill", age: 29}
var d1 = testRec{name: "Bob", age: 30}

var list0 *list.List

func main() {
	list0 = list.New()
	list0.Init()

	list0.PushBack(&d0)
	list0.PushBack(&d1)

	fmt.Println("Items on list: ", list0.Len())

	// 遍历列表并访问结构体字段
	for e := list0.Front(); e != nil; e = e.Next() {
		// 类型断言为指针类型
		if data, ok := e.Value.(*testRec); ok {
			fmt.Printf("Name: %s, Age: %d\n", data.name, data.age)
		} else {
			fmt.Println("Wrong type")
		}
	}
}

关键修改:

  1. 将类型断言从 data.(testRec) 改为 data.(*testRec)
  2. 使用指针类型来访问结构体字段

运行结果:

Items on list:  2
Name: Bill, Age: 29
Name: Bob, Age: 30

如果你确实想存储值类型而不是指针,可以这样修改:

package main

import (
	"container/list"
	"fmt"
)

type testRec struct {
	name string
	age  int
}

var d0 = testRec{name: "Bill", age: 29}
var d1 = testRec{name: "Bob", age: 30}

var list0 *list.List

func main() {
	list0 = list.New()
	list0.Init()

	// 存储值类型而不是指针
	list0.PushBack(d0)
	list0.PushBack(d1)

	fmt.Println("Items on list: ", list0.Len())

	for e := list0.Front(); e != nil; e = e.Next() {
		// 类型断言为值类型
		if data, ok := e.Value.(testRec); ok {
			fmt.Printf("Name: %s, Age: %d\n", data.name, data.age)
		} else {
			fmt.Println("Wrong type")
		}
	}
}

两种方式都可以正常工作,选择取决于你的具体需求。

回到顶部