根据循环中的子字符串匹配填充结构

问题描述 投票:0回答:1

如果我们看一下下面的代码,我们如何用从一段字符串中获取的值填充一个结构变量? 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

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

string go struct slice
1个回答
1
投票

代码的一个可能问题是您正在使用 strings.SplitAfterN 将列表的元素按“:”拆分,但此函数将在每个 pair1 的第一个子字符串中包含分隔符。例如,如果您有 op:count,它会将其拆分为 op: 和 count。这意味着您的结构字段将在开头有一个额外的冒号,这可能不是您想要的。

一个可能的解决方案是改用 strings.SplitN,这将从两个子字符串中排除分隔符2。例如,如果您有 op:count,它会将其拆分为 op 和 count。这样,您的结构字段将只有没有任何冒号的值。

代码的另一个可能问题是,在将值分配给结构字段之前,您没有从值中删除任何空格。如果您的输入列表中有空格或换行符,这可能会导致一些意外行为。例如,如果您有“文件:/tmp/file1.txt ", 它将分配 " /tmp/file1.txt " 到 c.File,这可能不是有效的文件名。

一个可能的解决方案是使用 strings.TrimSpace 在将每个值分配给您的结构字段2之前从每个值中删除任何前导或尾随空格。例如,如果您有“文件:/tmp/file1.txt ",它会在修剪后将"/tmp/file1.txt"分配给c.File。

好的,这是使用 strings.SplitN 和 strings.TrimSpace 重构代码的可能方法:

包主

进口( “调频” “操作系统” “字符串” )

类型配置结构{ 操作字符串 停止字符串 起始字符串 文件字符串 }

func ParseConfig(list []string) 配置{

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

}

函数主(){

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

}

© www.soinside.com 2019 - 2024. All rights reserved.