Golang中如何解决解析JSON时遇到无效字符'F'的问题

Golang中如何解决解析JSON时遇到无效字符’F’的问题 我完全不知道从何入手。我已经在谷歌上搜索过,但一无所获。我只是在尝试使用通道来理解 select{} 功能。控制台返回:invalid character ‘F’ looking for beginning of value

运行环境: https://goplay.space/#7dDoM19a8Xh

以下是我的代码,以防您正在使用移动设备查看:

package main

import (
	"fmt"
)

func main() {
	c, q := gen()

	receive(c, q)

	fmt.Println("about to exit")
}

func gen() (<-chan int, <-chan int) {
	c := make(chan int)
	q := make(chan int)

	go func() {
		for i := 0; i < 100; i++ {
			if i%2 == 0 {
				c <- i

			} else {
				q <- i
			}

		}
		close(q)
		close(c)
	}()

	return c, q
}
func receive(c, q <-chan int) {
	var msg1 int
	var msg2 int
	for {
		select {
		case msg1 = <-c:
			fmt.Println(msg1)
		case msg2 = <-q:
			fmt.Println(msg2)

		}
	}
}

更多关于Golang中如何解决解析JSON时遇到无效字符'F'的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

太棒了,非常感谢,我真的很感激你的帮助!我得仔细研究一下“逗号ok惯用法”。

更多关于Golang中如何解决解析JSON时遇到无效字符'F'的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这非常有趣。感谢您给我发送了多个示例。看来,为了让程序正确执行,for循环中需要一个条件。

我对 https://goplay.space 一无所知,但相同的代码在这里似乎运行良好(或者至少没有出现那个错误):Go Playground - The Go Programming Language,也许这是那个运行时的 bug?

是的,即使你忽略并行/并发的部分,只关注 for 循环,如果它没有定义任何条件(即它只是 for { 一些代码 }),那么除非循环体内有 break 或 return 语句,否则它将无限循环下去。

这个错误信息 invalid character 'F' looking for beginning of value 通常出现在JSON解析时,但你的代码中并没有JSON操作。错误实际上来自Go Playground的运行环境,它会在代码执行完成后自动尝试解析输出为JSON格式。

问题出现在你的 receive 函数中 - 它包含一个无限循环 for {},当通道关闭后仍然在读取,导致goroutine无法正常退出,触发了playground的超时机制。

以下是修复后的代码:

package main

import (
	"fmt"
)

func main() {
	c, q := gen()
	receive(c, q)
	fmt.Println("about to exit")
}

func gen() (<-chan int, <-chan int) {
	c := make(chan int)
	q := make(chan int)

	go func() {
		for i := 0; i < 100; i++ {
			if i%2 == 0 {
				c <- i
			} else {
				q <- i
			}
		}
		close(q)
		close(c)
	}()

	return c, q
}

func receive(c, q <-chan int) {
	for {
		select {
		case msg1, ok := <-c:
			if !ok {
				c = nil // 将关闭的通道设为nil,select会忽略nil通道
			} else {
				fmt.Println(msg1)
			}
		case msg2, ok := <-q:
			if !ok {
				q = nil // 将关闭的通道设为nil
			} else {
				fmt.Println(msg2)
			}
		}
		
		// 当两个通道都关闭时退出循环
		if c == nil && q == nil {
			return
		}
	}
}

或者使用更简洁的版本:

func receive(c, q <-chan int) {
	cOpen, qOpen := true, true
	var msg int
	
	for cOpen || qOpen {
		select {
		case msg, cOpen = <-c:
			if cOpen {
				fmt.Println(msg)
			}
		case msg, qOpen = <-q:
			if qOpen {
				fmt.Println(msg)
			}
		}
	}
}

关键修复点:

  1. 使用逗号ok模式检查通道是否关闭:msg, ok := <-c
  2. 当通道关闭后,将其设为nil或标记为关闭状态
  3. 在所有通道都关闭后正确退出循环

这样修改后,程序能够正常结束,不会触发playground的超时机制,也就不会出现那个JSON解析错误了。

回到顶部