Golang中append()与for循环的使用问题求助
问题修复:TCP连接数据读取与切片合并错误
问题点
- 循环结束后,
err和bytesReturned变量未定义,无法在循环外使用 - 执行
dataFile = append(dataFile, buff)时提示类型不匹配,无法合并切片
原代码
import ( "fmt" "net" "log" "bufio" "os" "io" ) func readData(conn net.Conn){ fmt.Println("Reading data...\n") // Create a new reader from conn reader := bufio.NewReader(conn) // Make a slice to hold all data being transmitted var dataFile []byte // Create a buffer to store information as it comes across conn buff := make([]byte, 4096) for { bytesReturned, err := reader.Read(buff) dataFile = append(dataFile, buff) if err != nil { if err != io.EOF{ log.Fatalln(err) } break //Break the loop when err returns EOF } } err = os.WriteFile("data.txt", dataFile, 0666) if err != nil { log.Fatal(err) } fmt.Println("Read", bytesReturned,"bytes.") } // Start of main -------------------------------- func main(){ //Listen on local port 80 listener, err := net.Listen("tcp", ":5555") if err != nil { log.Fatalln("Unable to bind port") } fmt.Println("Port 5555 binded...\n") //handle multiple connections for { conn, err := listener.Accept() if err != nil { log.Fatalln("Unable to accept connection...") } go readData(conn) } }
错误原因与修复
1. 循环外变量未定义
bytesReturned和err是在for循环内部用:=声明的局部变量,作用域仅限于循环内部,循环外部无法访问。
修复方式:在循环外提前声明变量,循环内用=赋值:
var bytesReturned int var err error for { bytesReturned, err = reader.Read(buff) // ... 其余代码 }
2. 切片append错误
append(dataFile, buff)的写法错误,因为append接收单个元素或展开的切片。正确做法是用...展开有效数据切片,并且只追加Read返回的有效部分(buff[:bytesReturned]),避免混入缓冲区旧数据:
dataFile = append(dataFile, buff[:bytesReturned]...)
修复后的完整代码
import ( "fmt" "io" "log" "net" "bufio" "os" ) func readData(conn net.Conn) { fmt.Println("Reading data...\n") reader := bufio.NewReader(conn) var dataFile []byte buff := make([]byte, 4096) var bytesReturned int var err error for { bytesReturned, err = reader.Read(buff) if bytesReturned > 0 { dataFile = append(dataFile, buff[:bytesReturned]...) } if err != nil { if err != io.EOF { log.Fatalln(err) } break } } err = os.WriteFile("data.txt", dataFile, 0666) if err != nil { log.Fatal(err) } fmt.Println("Read", len(dataFile), "bytes.") } func main() { listener, err := net.Listen("tcp", ":5555") if err != nil { log.Fatalln("Unable to bind port") } fmt.Println("Port 5555 binded...\n") for { conn, err := listener.Accept() if err != nil { log.Fatalln("Unable to accept connection...") } go readData(conn) } }
内容的提问来源于stack exchange,提问作者MFC-4
相关产品推荐
相关产品推荐

