Golang中chan int切片编译错误问题

Golang中chan int切片编译错误问题 我正在编写我的第一个Go程序,遇到了一个无法理解的编译错误。以下是我修改过的代码片段,可以重现该问题:

package main

import "fmt"

func main() {
	var list1 []string
	var indexchan []chan int
	item := "dummy"
	
	i := 0
	for ; i < 10; i++ {
		list1 = append(list1, item)
		
		// 每次迭代创建1个goroutine和1个独立通道
		c := make(chan int)
		indexchan = append(indexchan, c)
		go doSomeStuff(c)
		
		if item == "" { 
			// 在我的代码中,"item"是每次循环重新赋值的变量
			// 并传递给doSomeStuff进行处理
			fmt.Println("遇到空值,中断循环...")
			break
		}
	}
	
	list2 := make([]string, i)
	list3 := make([]string, i)
	var item2 string
	var item3 string
	for i := range list1 {
		item2 = <-indexchan[i]
		item3 = <-indexchan[i]
		list2[i] = item2
		list3[i] = item3
	}
}

func doSomeStuff(c chan int) {
	a := "result1"
	b := "result2"
	c <- a
	c <- b
}

使用"go run"命令返回:

tmp.go:34:9: cannot use <-indexchan[i] (type int) as type string in assignment
tmp.go:35:9: cannot use <-indexchan[i] (type int) as type string in assignment
tmp.go:44:4: cannot use a (type string) as type int in send
tmp.go:45:4: cannot use b (type string) as type int in send

出于某种原因,"indexchan[i]“本应是chan int切片的一个索引,却被识别为int类型。在稍微调整代码使其能够编译后,借助reflect.TypeOf发现indexchan和indexchan[i]实际上分别是”[]chan int"和"chan int"类型。

那么对于这个错误发生的原因有什么想法吗? 谢谢。


更多关于Golang中chan int切片编译错误问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

哦,好的!我完全理解错了,感谢您的澄清!😊

更多关于Golang中chan int切片编译错误问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题是 indexchan[i] 确实是 chan int 类型,但你试图从中接收一个 int 值(<-indexchan[i] 从通道接收一个整数)并将其赋值给一个 string 类型变量。这就解释了这类错误:cannot use <-indexchan[i] (type int) as type string in assignment

至于 cannot use a (type string) as type int in send 错误,doSomeStuff 接收的是 c chan int 参数,但你却试图通过它发送一个 string 类型的值,这同样是不正确的。

总而言之,当你声明某种类型的通道时,你只能从该通道接收或通过该通道发送该类型的值。而在你的代码中,你既将接收的整数值赋给了字符串变量,又试图通过整数通道发送字符串值。

问题出在通道类型不匹配。你定义的是 []chan int(整型通道切片),但在 doSomeStuff 函数中却试图发送字符串到这些通道中,同时从这些通道接收时又试图将整数值赋给字符串变量。

以下是修正后的代码:

package main

import "fmt"

func main() {
	var list1 []string
	var indexchan []chan string  // 改为字符串通道
	item := "dummy"
	
	i := 0
	for ; i < 10; i++ {
		list1 = append(list1, item)
		
		// 创建字符串通道
		c := make(chan string)
		indexchan = append(indexchan, c)
		go doSomeStuff(c)
		
		if item == "" { 
			fmt.Println("遇到空值,中断循环...")
			break
		}
	}
	
	list2 := make([]string, i)
	list3 := make([]string, i)
	var item2 string
	var item3 string
	for i := range list1 {
		item2 = <-indexchan[i]
		item3 = <-indexchan[i]
		list2[i] = item2
		list3[i] = item3
	}
	
	fmt.Printf("list2: %v\n", list2)
	fmt.Printf("list3: %v\n", list3)
}

func doSomeStuff(c chan string) {
	a := "result1"
	b := "result2"
	c <- a
	c <- b
}

如果你确实需要整型通道,那么应该发送和接收整数值:

package main

import "fmt"
import "strconv"

func main() {
	var list1 []string
	var indexchan []chan int  // 保持为整型通道
	item := "dummy"
	
	i := 0
	for ; i < 10; i++ {
		list1 = append(list1, item)
		
		c := make(chan int)
		indexchan = append(indexchan, c)
		go doSomeStuff(c)
		
		if item == "" { 
			fmt.Println("遇到空值,中断循环...")
			break
		}
	}
	
	list2 := make([]string, i)
	list3 := make([]string, i)
	for i := range list1 {
		item2 := <-indexchan[i]  // 接收int值
		item3 := <-indexchan[i]  // 接收int值
		list2[i] = strconv.Itoa(item2)  // 转换为字符串
		list3[i] = strconv.Itoa(item3)  // 转换为字符串
	}
	
	fmt.Printf("list2: %v\n", list2)
	fmt.Printf("list3: %v\n", list3)
}

func doSomeStuff(c chan int) {
	a := 1  // 整数值
	b := 2  // 整数值
	c <- a
	c <- b
}

编译错误的原因是类型系统严格检查通道的发送和接收操作:chan int 只能发送和接收 int 类型的数据,不能处理字符串。

回到顶部