结构体内引用函数,则该函数的运行过程令人难以理解

1. 运行环境

go 1.17

2. 问题描述?

package main

import (
    "fmt"
    "log"
)

type ConChan struct {
    ItemChan chan interface{}
}

func main() {
    e := &ConChan{
        ItemChan: ItemSave(),
    }
    e.ConRun(1,2,3,4,5)
}

func ItemSave() chan interface{} {
    out := make(chan interface{})
    go func() {
        for {
            item := <-out
            log.Printf("%s", item)
            fmt.Println(item)
        }
    }()
    return out

}

func (e *ConChan) ConRun(seeds ...int) {
    for _, i := range seeds {
        go func(i int) {
            e.ItemChan <- i
        }(i)

    }
}

问题一、这段代码,在ConChan结构体中的ItemChan在main中被初始化为ItemSave(),即return out,
在e.ConRun()时会往e.ItemChan 即out中写数据。我不理解这里为什么会触发ItemSave()中的log.Printf(“%s”, item),是每写一次就触发一次函数吗?
问题二、这段代码运行无结果,问题出在哪?

3. 您期望得到的结果?

将传入的 e.ConRun(1,2,3,4,5)打印出来。

4. 您实际得到的结果?

无运行结果,也无错误信息。

最佳答案
  1. 结构体初始化的时候函数就开始运行了,里面创建的携程从out 读取数据 此时是阻塞、等待写入的,调用ConRun的时候写入一个上面新建的携程 out这里就读取到打印了
  2. 可以在e.ConRun(1,2,3,4,5) 下面加一段 time.Sleep(time.Second * 1)
1年前 评论
Mgone (楼主) 1年前
讨论数量: 3
  1. 结构体初始化的时候函数就开始运行了,里面创建的携程从out 读取数据 此时是阻塞、等待写入的,调用ConRun的时候写入一个上面新建的携程 out这里就读取到打印了
  2. 可以在e.ConRun(1,2,3,4,5) 下面加一段 time.Sleep(time.Second * 1)
1年前 评论
Mgone (楼主) 1年前

你添加到的变量是e.ItemChan,显示的数据是out局部块变量,所以不会根据添加的数据后显示。 ItemSave 要显示的数据用e.ItemChan并且把这个函数作为ConChan的函数,运行在ConRun之前。

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!