json

仓颉通过扩展标准库(stdx)提供两个 JSON 包:

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "json" with this command: npx skills add kong-baiming/cangjie-dev/kong-baiming-cangjie-dev-json

仓颉语言 JSON 编解码 Skill

  1. 概述

仓颉通过扩展标准库(stdx)提供两个 JSON 包:

包 导入 适用场景

JSON 数据层 import stdx.encoding.json.*

解析/构建 JSON 值,适合简单读写

JSON 流式处理 import stdx.encoding.json.stream.*

流式处理,自定义类型与 JSON 互转,适合复杂场景

使用前需配置好 stdx,详见 cangjie-stdx Skill

  1. JSON 数据层(stdx.encoding.json)

2.1 JsonValue 类型体系

类 对应 JSON 获取值

JsonObject

{...}

get(key): Option<JsonValue> 、operator: JsonValue

JsonArray

[...]

get(index): Option<JsonValue> 、operator: JsonValue

JsonString

"..."

getValue(): String

JsonInt

整数 getValue(): Int64

JsonFloat

浮点数 getValue(): Float64

JsonBool

true/false

getValue(): Bool

JsonNull

null

通过 kind(): JsonKind 方法可判断类型,JsonKind 枚举值:JsObject 、JsArray 、JsString 、JsInt 、JsFloat 、JsBool 、JsNull 。

2.2 解析 JSON 字符串

import stdx.encoding.json.*

main() { let str = ##"{"name": "Alice", "age": 30, "scores": [90, 85]}"## let jv = JsonValue.fromStr(str)

// 访问对象字段
let obj = jv.asObject()
let name = obj["name"].asString().getValue()    // "Alice"
let age = obj["age"].asInt().getValue()          // 30

// 访问数组元素
let scores = obj["scores"].asArray()
let first = scores[0].asInt().getValue()         // 90
println("${name}, ${age}, ${first}")

}

  • JsonValue.fromStr(s) 将字符串解析为 JsonValue ,失败抛出 JsonException

  • asObject() / asArray() / asInt() 等向下转换,类型不符抛出 JsonException

2.3 构建 JSON

import stdx.encoding.json.*

main() { let obj = JsonObject() obj.put("name", JsonString("Bob")) obj.put("age", JsonInt(25)) obj.put("active", JsonBool(true))

let arr = JsonArray()
arr.add(JsonInt(1))
arr.add(JsonInt(2))
obj.put("tags", arr)

println(obj.toString())
// {"name":"Bob","age":25,"active":true,"tags":[1,2]}

println(obj.toJsonString())
// 带缩进换行的格式化输出

}

2.4 类型判断与安全访问

import stdx.encoding.json.*

main() { let str = ##"{"value": 42}"## let jv = JsonValue.fromStr(str) let obj = jv.asObject()

// 使用 get() 返回 Option,安全访问
match (obj.get("value")) {
    case Some(v) => println(v.asInt().getValue())   // 42
    case None => println("key not found")
}

// 使用 containsKey 检查
if (obj.containsKey("value")) {
    println(obj["value"].asInt().getValue())
}

// 使用 kind() 进行类型分发
let val = obj["value"]
match (val.kind()) {
    case JsInt => println("整数: ${val.asInt().getValue()}")
    case JsString => println("字符串: ${val.asString().getValue()}")
    case _ => println("其他类型")
}

}

  1. JSON 流式处理(stdx.encoding.json.stream)

适合自定义类型与 JSON 的互转,通过 JsonWriter 序列化、JsonReader 反序列化。

3.1 JsonWriter 序列化

import stdx.encoding.json.stream.* import std.io.{ByteBuffer, readToEnd}

main() { let buf = ByteBuffer() let writer = JsonWriter(buf)

writer.startObject()
writer.writeName("name").writeValue("Alice")
writer.writeName("age").writeValue(30)
writer.writeName("scores")
writer.startArray()
writer.writeValue(90)
writer.writeValue(85)
writer.endArray()
writer.endObject()
writer.flush()

println(String.fromUtf8(readToEnd(buf)))
// {"name":"Alice","age":30,"scores":[90,85]}

}

3.2 JsonReader 反序列化

import stdx.encoding.json.stream.* import std.io.ByteBuffer

main() { let jsonStr = ##"{"name":"Alice","age":30}"## var buf = ByteBuffer() unsafe { buf.write(jsonStr.rawData()) } let reader = JsonReader(buf)

reader.startObject()
while (let Some(token) &#x3C;- reader.peek()) {
    if (token == EndObject) {
        break
    }
    let key = reader.readName()
    match (key) {
        case "name" =>
            let name: String = reader.readValue&#x3C;String>()
            println("name = ${name}")
        case "age" =>
            let age: Int64 = reader.readValue&#x3C;Int64>()
            println("age = ${age}")
        case _ => reader.skip()
    }
}
reader.endObject()

}

  • peek(): Option<JsonToken> 查看下一个 token 类型,不消耗

  • readName() 读取字段名,readValue<T>() 读取值(T 须实现 JsonDeserializable<T> )

  • skip() 跳过当前值

3.3 自定义类型序列化(JsonSerializable)

实现 JsonSerializable 接口使自定义类型支持 writeValue :

import stdx.encoding.json.stream.* import std.io.{ByteBuffer, readToEnd}

class Image <: JsonSerializable { var width: Int64 = 0 var height: Int64 = 0 var title: String = ""

public func toJson(w: JsonWriter): Unit {
    w.startObject()
    w.writeName("width").writeValue(width)
    w.writeName("height").writeValue(height)
    w.writeName("title").writeValue(title)
    w.endObject()
}

}

main() { let img = Image() img.width = 800 img.height = 600 img.title = "仓颉示例"

let buf = ByteBuffer()
let writer = JsonWriter(buf)
writer.writeValue(img)
writer.flush()
println(String.fromUtf8(readToEnd(buf)))
// {"width":800,"height":600,"title":"仓颉示例"}

}

3.4 自定义类型反序列化(JsonDeserializable)

实现 JsonDeserializable<T> 接口使自定义类型支持 readValue<T>() :

import stdx.encoding.json.stream.* import std.io.ByteBuffer

class User <: JsonDeserializable<User> { var name: String = "" var age: Int64 = 0

public static func fromJson(r: JsonReader): User {
    let u = User()
    r.startObject()
    while (let Some(token) &#x3C;- r.peek()) {
        if (token == EndObject) {
            break
        }
        match (r.readName()) {
            case "name" => u.name = r.readValue&#x3C;String>()
            case "age" => u.age = r.readValue&#x3C;Int64>()
            case _ => r.skip()
        }
    }
    r.endObject()
    return u
}

}

main() { let jsonStr = ##"{"name":"Bob","age":25}"## var buf = ByteBuffer() unsafe { buf.write(jsonStr.rawData()) } let reader = JsonReader(buf) let user = reader.readValue<User>() println("${user.name}, ${user.age}") // Bob, 25 }

3.5 WriteConfig 格式控制

import stdx.encoding.json.stream.* import std.io.{ByteBuffer, readToEnd}

main() { let buf = ByteBuffer() let writer = JsonWriter(buf)

// 使用 pretty 格式(带换行和 4 空格缩进)
writer.writeConfig = WriteConfig.pretty

writer.startObject()
writer.writeName("key").writeValue("value")
writer.endObject()
writer.flush()
println(String.fromUtf8(readToEnd(buf)))
// {
//     "key": "value"
// }

}

预设 说明

WriteConfig.compact

紧凑格式,无空格换行(默认)

WriteConfig.pretty

格式化输出,4 空格缩进

可自定义属性:newline 、indent 、useSpaceAfterSeparators 、htmlSafe 、dateTimeFormat 。

3.6 readValue 内置支持类型

readValue<T>() 和 writeValue(v) 已内置支持以下类型(无需自行实现接口):

类别 类型

整数 Int8 ~ Int64 ,UInt8 ~ UInt64

浮点 Float16 ~Float64

布尔 Bool

字符串 String

集合 Array<T> 、ArrayList<T> 、HashMap<String, T>

可选 Option<T>

其他 BigInt 、Decimal 、DateTime (RFC 3339 格式)

  1. 数据层与流式处理的选择

场景 推荐

解析未知结构的 JSON JsonValue.fromStr()

  • kind() 判断

简单读取已知字段 JsonValue.fromStr()

  • asObject()["key"]

手动构建 JSON 输出 JsonObject / JsonArray

  • put / add

自定义类型 ↔ JSON 互转 JsonSerializable / JsonDeserializable<T>

  • 流式 API

大数据量流式处理 JsonReader / JsonWriter

  1. 注意事项

要点 说明

stdx 配置 JSON 包属于 stdx,需先下载配置(详见 cangjie-stdx Skill)

异常处理 fromStr() 解析失败、类型转换不匹配均抛出 JsonException

operator[] vs get()

operator[] 键/索引不存在时抛异常;get() 返回 Option ,更安全

JsonReader 状态 startObject/endObject 、startArray/endArray 须严格配对

flush JsonWriter 写完后须调用 flush() 确保数据输出

转义字符 fromStr 支持 JSON 标准转义:\b 、\f 、\n 、\r 、\t 、\uXXXX 、\ 、" 、/

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

inner_annotation

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

array

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

struct

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

entry_args

No summary provided by upstream source.

Repository SourceNeeds Review