在循环中根据子字符串匹配填充一个结构体。

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

Filling a struct based on substring matches within a loop

问题

如果我们看一下以下代码,我们如何使用从字符串切片中获取的值填充一个结构体变量?https://go.dev/play/p/KkcPzr5r28w

package main

import (
	"fmt"
	"os"
	"strings"
)

type Config struct {
	Operation string
	Stop      string
	Start     string
	File      string
}

func ParseConfig(list []string) Config {

	var c Config
	for _, elem := range list {
		if strings.Contains(elem, "op:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.Operation = subList[1]
		} else if strings.Contains(elem, "stop:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.Stop = subList[1]
		} else if strings.Contains(elem, "start:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.Start = subList[1]
		} else if strings.Contains(elem, "file:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.File = subList[1]
		}
	}
	return c
}

func main() {

	c := ParseConfig(os.Args[1:])
	fmt.Println(c) // {count the  quick /tmp/file1.txt}
}

当使用以下参数调用该程序时,它没有返回正确的响应:

go run scan.go op:count start:quick stop:the file:/tmp/file1.txt

我想知道出了什么问题?重构代码以解决问题的最佳方法是什么?

英文:

If we take a look at the following code, how can we fill a struct variable with values taken from a slice of strings? https://go.dev/play/p/KkcPzr5r28w

package main

import (
	"fmt"
	"os"
	"strings"
)

type Config struct {
	Operation string
	Stop      string
	Start     string
	File      string
}

func ParseConfig(list []string) Config {

	var c Config
	for _, elem := range list {
		if strings.Contains(elem, "op:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.Operation = subList[1]
		} else if strings.Contains(elem, "stop:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.Stop = subList[1]
		} else if strings.Contains(elem, "start:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.Start = subList[1]
		} else if strings.Contains(elem, "file:") {
			subList := strings.SplitAfterN(elem, ":", 2)
			c.File = subList[1]
		}
	}
	return c
}

func main() {

	c := ParseConfig(os.Args[1:])
	fmt.Println(c) // {count the  quick /tmp/file1.txt}
}

This program doesn't return the right response when invoked with these parameters:

go run scan.go op:count start:quick stop:the file:/tmp/file1.txt

I was wondering what's wrong? What is the best way to refactor the code to solve the problem?

答案1

得分: 0

希望我已经修复了它,感谢Gophers社区的帮助:https://go.dev/play/p/u_Dc7ctbsib

package main

import (
	"fmt"
	"strings"
)

type Config struct {
	Operation string
	Stop      string
	Start     string
	File      string
}

func main() {
	list := []string{"op:count", "start:quick", "stop:the", "file:/tmp/file1.txt"}
	fmt.Println(list)
	var c Config
	for _, v := range list {
		if strings.HasPrefix(v, "op:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.Operation = subList[1]
		} else if strings.Contains(v, "stop:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.Stop = subList[1]
		} else if strings.Contains(v, "start:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.Start = subList[1]
		} else if strings.Contains(v, "file:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.File = subList[1]
		}
	}
	fmt.Println(c) // {count the  quick /tmp/file1.txt}

}

由于"stop:the"错误地匹配了"op:",导致Operation最终被设置为"the"而不是"count"。问题似乎已经通过将strings.Contains替换为strings.HasPrefix得到解决。

英文:

Hopefully I've fixed it, thanks to Gophers's community: https://go.dev/play/p/u_Dc7ctbsib

package main

import (
	"fmt"
	"strings"
)

type Config struct {
	Operation string
	Stop      string
	Start     string
	File      string
}

func main() {
	list := []string{"op:count", "start:quick", "stop:the", "file:/tmp/file1.txt"}
	fmt.Println(list)
	var c Config
	for _, v := range list {
		if strings.HasPrefix(v, "op:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.Operation = subList[1]
		} else if strings.Contains(v, "stop:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.Stop = subList[1]
		} else if strings.Contains(v, "start:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.Start = subList[1]
		} else if strings.Contains(v, "file:") {
			subList := strings.SplitAfterN(v, ":", 2)
			c.File = subList[1]
		}
	}
	fmt.Println(c) // {count the  quick /tmp/file1.txt}

}



Due to the fact that "stop:the" also wrongly matches "op:", Operation is finally set to "the" instead of "count". The problem seems to be solved now that strings.Contains was replaced with strings.HasPrefix.

huangapple
  • 本文由 发表于 2023年2月18日 20:44:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75493433.html
匿名

发表评论

匿名网友

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

确定