使用range函数无法使用变量。

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

There is no way to use variable using range

问题

我已经编写了一个简单的脚本,它将读取/proc/cpuinfo并返回一个包含有关核心信息的[]map[string]string

问题是,我无法在范围内使用这些值,它总是给我最后一个CPU的信息。

我尝试在各个地方使用闭包,但没有成功。我还尝试在循环中将变量复制到本地,但仍然没有成功。

以下是我的代码:

func GetCpuInfo() CpuInfo {
    cpus, err := os.Open("/proc/cpuinfo")
    if err != nil {
        log.Fatalln("Cannot open /proc/cpuinfo")
    }
    defer cpus.Close()
    s := bufio.NewScanner(cpus)
    cpuCores := make(CpuCores, 0)
    core := map[string]string{}
    for s.Scan() {
        txt := s.Text()
        //复制变量也不起作用
        core := core

        if len(txt) == 0 {
            //在这里使用闭包也不起作用
            cpuCores = append(cpuCores, core)
            continue
        }
        fields := strings.Split(txt, ":")
        if len(fields) < 2 {
            continue
        }
        //在这里使用闭包也不起作用
        var k, v = strings.TrimSpace(fields[0]), strings.TrimSpace(fields[1])
        core[k] = v
    }
    return CpuInfo{
        Cores:    cpuCores,
        CpuCount: uint(runtime.NumCPU()),
        Brand:    cpuCores[0]["vendor_id"],
        Model:    cpuCores[0]["model name"],
    }
}

从代码中可以看出,似乎没有办法使用这个变量,或者我确实忽略了一些重要的点。

英文:

I have written a simple script that will read the /proc/cpuinfo and return a []map[string]string containing the info about the cores.

The problem is I am unable to use the values inside the range it always gives me the info of the last CPU.

I tried using closures literally everywhere with no success. And also I tried to copy the variables locally in the loop and still no success.

Here is my code

func GetCpuInfo() CpuInfo {
	cpus, err := os.Open(&quot;/proc/cpuinfo&quot;)
	if err != nil {
		log.Fatalln(&quot;Cannot open /proc/cpuinfo&quot;)
	}
	defer cpus.Close()
	s := bufio.NewScanner(cpus)
	cpuCores := make(CpuCores, 0)
	core := map[string]string{}
	for s.Scan() {
		txt := s.Text()
//copying the variable also does not work
		core := core

		if len(txt) == 0 {
//tried to use closure here with no success
			cpuCores = append(cpuCores, core)
			continue
		}
		fields := strings.Split(txt, &quot;:&quot;)
		if len(fields) &lt; 2 {
			continue
		}
//using closure here wont work either
		var k, v = strings.TrimSpace(fields[0]), strings.TrimSpace(fields[1])
		core[k] = v
	}
	return CpuInfo{
		Cores:    cpuCores,
		CpuCount: uint(runtime.NumCPU()),
		Brand:    cpuCores[0][&quot;vendor_id&quot;],
		Model:    cpuCores[0][&quot;model name&quot;],
	}
}

As you see from the code seems like there is no way to use this variable or i am really missing some huge point.

答案1

得分: 1

看起来你想做这样的事情:

type CpuCore struct {
    VendorID  string
    ModelName string
}

func GetCpuInfo() CpuInfo {
    cpus, err := os.Open("/proc/cpuinfo")
    if err != nil {
        log.Fatalln("无法打开 /proc/cpuinfo")
    }
    defer cpus.Close()
    s := bufio.NewScanner(cpus)
    cpuCores := make([]CpuCore, 0)
    for s.Scan() {
        txt := s.Text()

        fields := strings.Split(txt, ":")

        if len(fields) < 2 {
            continue
        }

        var k, v = strings.TrimSpace(fields[0]), strings.TrimSpace(fields[1])
        cpuCores = append(cpuCores, CpuCore{VendorID: k, ModelName: v})
    }
    return CpuInfo{
        Cores:    cpuCores,
        CpuCount: uint(runtime.NumCPU()),
        Brand:    cpuCores[0].VendorID,
        Model:    cpuCores[0].ModelName,
    }
}

我假设你有一个名为 CpuCore 的结构体,并且你想创建一个名为 cpuCores 的数组。

如果你能提供更多的代码和类型信息,我们或许可以尝试运行这段代码。

英文:

Seems like you want to do something like:

struct CpuCore {
    VendorID string
    ModelName string
}

func GetCpuInfo() CpuInfo {
    cpus, err := os.Open(&quot;/proc/cpuinfo&quot;)
    if err != nil {
        log.Fatalln(&quot;Cannot open /proc/cpuinfo&quot;)
    }
    defer cpus.Close()
    s := bufio.NewScanner(cpus)
    cpuCores := make(CpuCore, 0)
    for s.Scan() {
        txt := s.Text()

        fields := strings.Split(txt, &quot;:&quot;)

        if len(fields) &lt; 2 {
            continue
        }

        var k, v = strings.TrimSpace(fields[0]), strings.TrimSpace(fields[1])
        cpuCores = append(cpuCores, CpuCores{VendorID: k, ModelName: v})
    }
    return CpuInfo{
        Cores:    cpuCores,
        CpuCount: uint(runtime.NumCPU()),
        Brand:    cpuCores[0].VendorID,
        Model:    cpuCores[0].ModelName,
    }
}

I'm assuming you have a struct CpuCore and that you want to make an array of them called cpuCores.

Perhaps if you include more of your code and types that would allow us to actually try to run this code.

答案2

得分: 0

我刚刚发现了一种方法,通过在追加之后重置核心变量来实现:

if len(txt) == 0 {
				cpuCores = append(cpuCores, core)
				core=map[string]string{}
			}

像这样,但我不确定这是否会导致内存泄漏。

英文:

I just found the way around by resetting the core variable after appending it

if len(txt) == 0 {
				cpuCores = append(cpuCores, core)
				core=map[string]string{}
			}

like this but I am not sure if this can cause a memory leak

答案3

得分: -1

在Go语言中,map类型是引用类型,我们不能通过:=来复制一个map。

你应该在每次循环中创建一个新的map。

英文:
//copying the variable also does not work
        core := core

In golang, map types are reference types and we can not copy a map by :=.

You should make a new map in every loop.

huangapple
  • 本文由 发表于 2017年3月1日 09:06:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/42521462.html
匿名

发表评论

匿名网友

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

确定