Golang校验字符串是否JSON格式方法Json.Valid源码解析

开发 前端
本篇文章我们来剖析下源码看下 Encoding/json 包中 Valid 方法的实现原理。

本文来剖析一下json.Valid方法的源码。

json.Valid方法源码

json.Valid方法定义:

// Valid reports whether data is a valid JSON encoding.
func Valid(data []byte) bool {
	scan := newScanner()
	defer freeScanner(scan)
	return checkValid(data, scan) == nil
}

scan := newScanner() 获取一个 scanner 类型的对象,关键的是checkValid方法,checkValid源码如下:

// checkValid verifies that data is valid JSON-encoded data.
// scan is passed in for use by checkValid to avoid an allocation.
func checkValid(data []byte, scan *scanner) error {
	scan.reset()
	for _, c := range data {
		scan.bytes++
		if scan.step(scan, c) == scanError {
			return scan.err
		}
	}
	if scan.eof() == scanError {
		return scan.err
	}
	return nil
}

首先调用了scan.reset(),主要是初始化scanner关键字段,如下:

s.step = stateBeginValue
s.parseState = s.parseState[0:0]
s.err = nil
s.endTop = false

然后就是通过遍历要校验的数据,使用状态机方式做判断。

使用一个示例来看检测过程

接下来以 {"a":"b"} 为例,来看下整个的判断过程:

  1. scan.reset()执行后将将step赋值为stateBeginValue;
  2. 首先判断“{”,使用stateBeginValue方法进行判断,发现是,将step赋值为stateBeginStringOrEmpty,执行pushParseState往parseState追加表示是key的值0;
  3. 接下来判断“"”,使用stateBeginStringOrEmpty方法进行判断,紧接着使用stateBeginString方法进行判断,发现是,将step赋值为stateInString;
  4. 接下来判断“a”,使用stateInString方法进行判断,发现是,继续遍历;
  5. 接下来判断“"”,使用stateInString方法进行判断,发现是,将step赋值为stateEndValue;
  6. 接下来判断“:”,使用stateEndValue方法进行判断,看parseState最后一个值,发现是key部分,检测到时“:”,将parseState最后一个值置为value部分标识,将step赋值为stateBeginValue;
  7. 接下来判断“"”,使用stateBeginValue方法进行判断,发现是,将step赋值为stateInString
  8. 接下来判断“b”,使用stateInString方法进行判断,发现是,继续往下遍历;
  9. 接下来判断“"”,使用stateInString方法进行判断,发现是,将step赋值为stateEndValue;
  10. 接下来判断“}”,使用stateEndValue方法进行判断,看parseState最后一个值,发现是value部分,检测到了“}”,如果parseStat长度为0,step赋值stateEndTop,如果不为0,将step赋值为stateEndValue,检测结束,返回结果。

小结

大家可以结合源码和本文来自己体会一下整个的检测过程。json.Valid方法会把例如123、true、false、null等也认为是json编码,这可能不是大家在开发过程中想要的结果,所以下一篇文章会介绍基于json.Valid方法改造后的方法,完美得实现json格式校验。

责任编辑:姜华 来源: 今日头条
相关推荐

2023-07-31 09:13:13

ValidatorGolang

2010-01-07 16:55:06

JSON字符串

2013-07-23 06:39:49

Json字符串到JsoAndroid开发学习Json万能解析器

2009-03-23 14:14:33

JSONAJAXJavaScript

2021-09-30 07:26:15

YamlJsonXml

2015-07-02 10:37:32

C#Json字符串类代码

2024-02-19 15:38:08

JsonPython字符串

2010-01-05 16:48:16

JSON 字符串

2010-01-06 17:06:05

Json格式

2010-01-07 15:52:23

JSON字符串

2010-02-01 16:46:07

C++格式化字符串

2010-01-06 16:33:04

JSON对象标记

2021-10-31 23:01:50

语言拼接字符串

2009-11-26 16:26:32

PHP字符串mbstr

2009-11-25 09:13:41

PHP数组转字符串PHP字符串转数组

2010-01-06 15:03:34

JSON格式封装

2020-06-28 08:26:41

Python开发工具

2024-01-04 09:17:03

前端开发CSV 格式JSON 字符串

2011-03-04 14:58:40

jqueryJSON

2010-07-14 12:39:30

Prel字符串
点赞
收藏

51CTO技术栈公众号