节点结构体切片中的未定义属性

huangapple go评论90阅读模式
英文:

undefined attributes in an slice of node structs

问题

我正在尝试通过实现一个随机图来学习Go语言。我在n.value和n.neigbours上遇到了错误,错误信息是undefined (type int has no field or method value)和undefined (type int has no field or method neigbours)。我无法理解这个编译错误,因为我在g.nodes = make([]node, g.nodesnr)中创建了一个新的节点切片。问题出在哪里呢?

package main

import (
	"fmt"
)

type node struct {
	value     int
	neigbours []int
}

type edge struct {
	source int
	sink   int
}

type graph struct {
	nodesnr, edgesnr int
	nodes            []node
	edges            chan edge
}

func main() {
	randomGraph()
}

func input(tname string) (number int) {
	fmt.Println("请输入" + tname + "的数量")
	fmt.Scan(&number)
	return
}

func randomGraph() (g graph) {
	g = graph{nodesnr: input("节点"), edgesnr: input("边")}
	g.addNodes()
	for i := 0; i < g.nodesnr; i++ {
		fmt.Println(g.nodes[i].value)
	}
	//g.addEdges()
	return
}

func (g *graph) addNodes() {
	g.nodes = make([]node, g.nodesnr)
	for n := range g.nodes {
		n.value = 2
		n.neigbours = nil
		return
	}
}

func (g *graph) addEdges() {
	g.edges = make(chan edge)
	for i := 0; i < g.edgesnr; i++ {
		//g.newEdge()
		return
	}
}

/*
 func (g* graph) newEdge(){
e := new(edge)
e.source, e.sink = rand.Intn(g.nodesnr), rand.Intn(g.nodesnr)
g.edges <-e*
//g.addEdge()
 }
*/

func (g *graph) edgeCheck(ep *edge) string {
	if ep.source == ep.sink {
		return "self"
	}
	//if(g.neigbourCheck(g.nodes[ep.source].neigbours, ep.sink) OR    g.neigbourCheck(g.nodes[ep.sink].neigbours, ep.source){
	//  return "present"

	return "empty"
}

func (g *graph) neigbourCheck(neigbours []node, node int) bool {
	for neigbour := range neigbours {
		if node == neigbour {
			return true
		}
	}
	return false
}

func (g *graph) addEdge() {
	e := <-g.edges
	switch etype := g.edgeCheck(&e); etype {
	case "present":
		fallthrough
	case "self":
		fmt.Println("self")
		//go g.newEdge()
	case "empty":
		//g.nodes[e.source] = append(g.nodes[e.source], e.sink),
		//g.nodes[e.sink] = append(g.nodes[e.sink], e.source)
		fmt.Println("empty")
	default:
		fmt.Println("something went wrong")
	}
}

Playground

英文:

er, I am trying to learn go by implementing a random graph. I get an error on n.value undefined (type int has no field or method value), and n.neigbours undefined (type int has no field or method neigbours). I can not understand that compilation error as i create a new slice of nodesnr size of empty nodes in the g.nodes = make([]node, g.nodesnr). What is the problem?

package main
import (
&quot;fmt&quot;
//&quot;math/rand&quot;
)
type node struct {
value     int
neigbours []int
}
type edge struct {
source int
sink   int
}
type graph struct {
nodesnr, edgesnr int
nodes            []node
edges            chan edge
}
func main() {
randomGraph()
}
func input(tname string) (number int) {
fmt.Println(&quot;input a number of &quot; + tname)
fmt.Scan(&amp;number)
return
}
func randomGraph() (g graph) {
g = graph{nodesnr: input(&quot;nodes&quot;), edgesnr: input(&quot;edges&quot;)}
g.addNodes()
for i := 0; i &lt; g.nodesnr; i++ {
fmt.Println(g.nodes[i].value)
}
//g.addEdges()
return
}
func (g *graph) addNodes() {
g.nodes = make([]node, g.nodesnr)
for n := range g.nodes {
n.value = 2
n.neigbours = nil
return
}
}
func (g *graph) addEdges() {
g.edges = make(chan edge)
for i := 0; i &lt; g.edgesnr; i++ {
//g.newEdge()
return
}
}
/*
func (g* graph) newEdge(){
e := new(edge)
e.source, e.sink = rand.Intn(g.nodesnr), rand.Intn(g.nodesnr)
g.edges &lt;-e*
//g.addEdge()
}
*/
func (g *graph) edgeCheck(ep *edge) string {
if ep.source == ep.sink {
return &quot;self&quot;
}
//if(g.neigbourCheck(g.nodes[ep.source].neigbours, ep.sink) OR    g.neigbourCheck(g.nodes[ep.sink].neigbours, ep.source){
//  return &quot;present&quot;
return &quot;empty&quot;
}
func (g *graph) neigbourCheck(neigbours []node, node int) bool {
for neigbour := range neigbours {
if node == neigbour {
return true
}
}
return false
}
func (g *graph) addEdge() {
e := &lt;-g.edges
switch etype := g.edgeCheck(&amp;e); etype {
case &quot;present&quot;:
fallthrough
case &quot;self&quot;:
fmt.Println(&quot;self&quot;)
//go g.newEdge()
case &quot;empty&quot;:
//g.nodes[e.source] = append(g.nodes[e.source], e.sink),
//g.nodes[e.sink] = append(g.nodes[e.sink], e.source)
fmt.Println(&quot;empty&quot;)
default:
fmt.Println(&quot;something went wrong&quot;)
}
}

Playground

答案1

得分: 3

你的错误出现在第47行

for n := range g.nodes 

在遍历切片时,当只使用一个值时,该值(n)将被设置为索引,索引的类型为int。你需要做的是将该行改为:

for _, n := range g.nodes 

这意味着你舍弃了索引,而将值放在n中。

编辑

n将是值的副本,这意味着对n所做的任何更改都不会影响切片中的节点。要编辑切片中的节点,你实际上应该获取索引而不是值:

for i := range g.nodes {
g.nodes[i].value = 2
g.nodes[i].neigbours = nil
return
}
英文:

Your error lies on line 47

for n := range g.nodes 

When iterating over a slice, when using only one value, that value (n) will be set to the index, which is of type int. What you need to do is to change the line to:

for _, n := range g.nodes 

This means that you discard the index but put the value in n instead.

Edit

n will be a copy of the value which means any changes made to n will not affect the node in the slice. To edit the node in the slice, you should actually get the index instead of the value:

for i := range g.nodes {
g.nodes[i].value = 2
g.nodes[i].neigbours = nil
return
}

huangapple
  • 本文由 发表于 2013年9月24日 17:33:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/18977819.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定