英文:
golang populate struct field from file
问题
我对golang的开发还比较新手,所以如果这是一个初级问题,我很抱歉。我没有看到类似的问题已经被问过;如果有的话,请指出来(谢谢)。
完整的代码(在我提问这个问题时的代码,因为它是可变的)在http://play.golang.org/p/idDp1E-vZo。
我声明了一个具有四个基本字段的结构体,并且我正在从本地文件系统中的文件中读取Node.ipaddr
的值(我在运行时获取fileName
的值作为一个标志;这段代码在上面提供的链接中被删除了)。
type Node struct {
hostname string
ipaddr string
pstatus string
ppid int
}
file, err := os.Open(fileName)
if err != nil {
panic(fmt.Sprintf("error opening %s: %v", fileName, err))
}
因为文件是按行分隔的,所以我认为使用bufio.Scanner
来从文件中读取数据是理想的。我在哪里遇到困难是如何优雅地将数据传递到结构体的元素中。
我创建了一个Node
元素的数组,并考虑了使用map
,但我不确定如何实际使用它(尚未确定)。
var nodes []*Node
var nodemap = make(map[string]*Node) //我甚至需要这个吗?
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "error reading from file:", err)
os.Exit(3)
}
//将scanner.Text()传递给Node.ipaddr
}
除了在一个索引的for
循环中包装scanner.Scan()
之外,我完全不确定如何继续下去。如果我在一个索引的for
循环中包装scanner.Scan()
,这个for
循环能够优雅地处理EOF吗?我猜我不确定在这种情况下索引的限制/最大比较值应该是什么。
一如既往,感谢您愿意提供的任何建议。
编辑:输入文件的格式如下:
10.1.1.1
10.1.1.2
10.1.1.3
我预计文件中会有大约150个条目,每行一个IPv4地址。
英文:
I'm pretty new to developing in golang, so if this is an elementary question I apologize. I didn't see a comparable question already asked; if there is one, please point me to it (thanks).
The full code (at the time of my asking this question, since it's not immutable) is at http://play.golang.org/p/idDp1E-vZo
I've declared a struct with four primitive fields, and I'm reading the values destined for Node.ipaddr
from a file on the local filesystem (I'm getting the value of fileName
as a flag at runtime; that code is trimmed out here but is in the link provided above.)
type Node struct {
hostname string
ipaddr string
pstatus string
ppid int
}
file, err := os.Open(fileName)
if err != nil {
panic(fmt.Sprintf("error opening %s: %v", fileName, err))
}
Because the file is line-delimited, I thought a bufio.Scanner
would be ideal for reading the data from the file. Where I am struggling is finding an elegant way to actually pass the data into the struct elements.
I created an array of Node
elements, and have considered a map
, but I am not sure how I'd make practical use of it (yet).
var nodes []*Node
var nodemap = make(map[string]*Node) //do I even need this?
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "error reading from file:", err)
os.Exit(3)
}
//pass scanner.Text() into Node.ipaddr
}
Short of wrapping scanner.Scan()
in an indexed for
loop, I'm not at all sure how to proceed. If I do wrap scanner.Scan()
in an indexed for
loop, will the for
loop be able to handle EOF elegantly -- I guess I'm not sure what the index limit/max comparison value should be in that case.
As always, thanks for any advice that you're willing to offer.
edit: The format of the input file is like this:
10.1.1.1
10.1.1.2
10.1.1.3
I anticipate approx 150 entries in the file, one IPv4 address per line.
答案1
得分: 2
你可以使用类似于这个
的代码:
func main() {
file := strings.NewReader(IPS) //os.Open(fileName)
var nodes []*Node
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "error reading from file:", err)
os.Exit(3)
}
ip := net.ParseIP(scanner.Text())
if ip != nil {
nodes = append(nodes, &Node{ipaddr: net.ParseIP(scanner.Text())})
}
}
for _, n := range nodes {
fmt.Printf("%s, %+v\n", n.ipaddr, n)
}
}
请注意,这只是一个示例代码,其中的IPS
和Node
是未定义的变量。你需要根据实际情况进行适当的修改。
英文:
You could use something along the lines of this
:
func main() {
file := strings.NewReader(IPS) //os.Open(fileName)
var nodes []*Node
scanner := bufio.NewScanner(file)
for scanner.Scan() {
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "error reading from file:", err)
os.Exit(3)
}
ip := net.ParseIP(scanner.Text())
if ip != nil {
nodes = append(nodes, &Node{ipaddr: net.ParseIP(scanner.Text())})
}
}
for _, n := range nodes {
fmt.Printf("%s, %+v\n", n.ipaddr, n)
}
}
答案2
得分: 2
你唯一缺少的是append
函数,用于将新节点添加到切片中。
nodes = append(nodes, &Node{ipaddr: scanner.Text()})
此外,你可以在for
循环中使用索引,同时将scanner.Scan()
作为条件。这样可以优雅地处理EOF
,同时允许你访问那个新的Node
(如果需要的话)。
for i := 0; scanner.Scan(); i++ {
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "error reading from file:", err)
os.Exit(3)
}
nodes = append(nodes, &Node{ipaddr: scanner.Text()})
fmt.Println(nodes[i])
}
完整代码:http://play.golang.org/p/RvMQp-jgWF
英文:
The only thing you're missing is the append
function to add a new node to the slice.
nodes = append(nodes, &Node{ipaddr: scanner.Text()})
Also, you can have an index on your for
loop while still having the scanner.Scan()
as the condition. This lets the EOF
be handled elegantly while still allowing you to access that new Node
if need be.
for i := 0; scanner.Scan(); i++ {
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "error reading from file:", err)
os.Exit(3)
}
nodes = append(nodes, &Node{ipaddr: scanner.Text()})
fmt.Println(nodes[i])
}
Full code: http://play.golang.org/p/RvMQp-jgWF
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论