使用动态类型
动态类型是运行时类型未知的数据的包装器。当处理来自外部源(如 JSON)的数据时,动态类型会有所帮助,这些外部源支持没有等效 Flux 类型的数据类型。
表不支持动态类型
Flux 表格不支持动态类型。 要在 Flux 表格中包含动态值,您必须将动态类型转换为 Flux 基本类型。有关将动态类型转换为基本类型并将其包含在表格中的完整示例,请参阅在表格中包含动态类型。
将 JSON 解析为 Flux 类型
动态类型的主要(但非唯一)用例是将 JSON 数据转换为原生 Flux 类型;特别是 Flux 数组和记录。
由于 Flux 中严格的类型规则,JSON 数据并非总是能顺利解析为原生 Flux 类型。最常见的原因是 Flux 数组要求所有子元素都为相同类型。JSON 数组允许元素具有不同的类型。
对于 Flux 记录(JSON 对象的推论),记录中的属性是记录类型的一部分。如果您有一个 JSON 对象数组,其中对象的模式不同,则该数组无法解析为 Flux 数组,因为数组中记录的类型不匹配。
动态类型提供了一种解决 JSON 和 Flux 类型之间差异的方法。
动态类型语法
Flux 没有为动态类型提供字面量语法。要将值强制转换为动态类型,请执行以下操作
- 导入
experimental/dynamic
包。 - 使用
dynamic.dynamic()
将值转换为动态类型。
import "experimental/dynamic"
dynamic.dynamic(v: "Example string")
// Returns dynamic(Example string)
引用动态类型中的值
使用方括号和点表示法来引用动态记录和数组中的值。使用 exists
运算符检查动态类型是否包含非空值。
引用动态记录中的值
import "experimental/dynamic"
record = {one: 1, two: 2, three: 3}
dynamicRecord = dynamic.dynamic(v: record)
dynamicRecord.one
// Returns dynamic(1)
dynamicRecord["two"]
// Returns dynamic(2)
引用动态数组中的值
import "experimental/dynamic"
arr = ["a", "b", "c"]
dynamicArr = dynamic.asArray(v: dynamic.dynamic(v: arr))
dynamicArr[0]
// Returns dynamic(a)
确保动态类型包含非空值
使用 exists
运算符检查动态类型是否包含非空值。如果您尝试访问空动态类型的成员,Flux 将返回错误。exists
可让您防止因尝试访问空动态类型中的成员而导致的错误。
对动态类型进行操作
将动态类型转换为 Flux 类型
基本类型
使用string()
将动态类型转换为字符串。string()
返回动态值的字符串表示形式。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: "string")
string(v: dynamicValue)
// Returns "string"
使用int()
将动态类型转换为整数。int()
返回动态值的整数等效值。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: "12")
int(v: dynamicValue)
// Returns 12
使用uint()
将动态类型转换为无符号整数(UInteger)。uint()
返回动态值的UInteger 等效值。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: "12")
uint(v: dynamicValue)
// Returns 12
使用float()
将动态类型转换为浮点值。float()
返回动态值的浮点等效值。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: "12.1")
float(v: dynamicValue)
// Returns 12.1
使用bool()
将动态类型转换为布尔值。bool()
返回动态值的布尔等效值。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: "true")
bool(v: dynamicValue)
// Returns true
使用duration()
将动态类型转换为持续时间值。duration()
返回动态值的持续时间等效值。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: 3000000000)
duration(v: dynamicValue)
// Returns 3s
使用time()
将动态类型转换为时间值。time()
返回动态值的时间等效值。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: 1640995200000000000)
time(v: dynamicValue)
// Returns 2022-01-01T00:00:00.000000000Z
使用bytes()
将动态类型转换为字节编码的字符串。bytes()
返回动态值的字节等效值。
import "experimental/dynamic"
dynamicValue = dynamic.dynamic(v: "Hello world!")
bytes(v: dynamicValue)
// Returns 0x48656c6c6f20776f726c6421
- 使用
string()
将动态类型转换为字符串。 - 导入
regexp
包并使用regexp.compile()
将字符串值转换为正则表达式类型。
import "experimental/dynamic"
import "regexp"
dynamicValue = dynamic.dynamic(v: "^[abc][123]{1,}")
stringValue = string(v: dynamicValue)
regexp.compile(v: stringValue)
// Returns /^[abc][123]{1,}/
复合类型
动态复合类型几乎总是来自处理字节编码的 JSON 字符串。以下所有示例均假设如此。
要将 JSON 数组转换为 Flux 数组
导入以下包
使用
dynamic.jsonParse()
将字节编码的 JSON 字符串解析为动态类型。使用
dynamic.asArray()
将动态类型的数组转换为动态类型数组。使用
array.map()
迭代数组中的每个元素,并显式地将动态类型转换为基本类型。
要将 JSON 对象转换为 Flux 记录
- 导入
experimental/dynamic
包 - 使用
dynamic.jsonParse()
将字节编码的 JSON 字符串解析为动态类型。 - 定义一个新的记录,并将动态类型的每个属性转换为基本类型。
JSON 对象
{"first-name": "John", "last-name": "Doe", "age": 42}
将 JSON 对象转换为 Flux 记录
import "experimental/dynamic"
json = jsonBytes // Byte-encoded JSON above
parsed = dynamic.jsonParse(data: json)
newRecord = {
fname: string(v: parsed["first-name"]),
lname: string(v: parsed["last-name"]),
age: int(v: parsed.age)
}
// newRecord returns {age: 42, fname: John, lname: Doe}
检查动态类型内部值的类型
使用dynamic.isType()
检查动态类型内部值的类型。
以下示例使用http/requests
包和Fruityvice API 返回有关苹果的 JSON 对象信息。
import "experimental/dynamic"
response = requests.get(url: "https://www.fruityvice.com/api/fruit/apple")
parsed = dynamic.jsonParse(data: response.body)
dynamic.isType(v: parsed.genus, type: "string")
// Returns true
dynamic.isType(v: parsed.nutritions, type: "array")
// Returns false
dynamic.isType(v: parsed.nutritions, type: "object")
// Returns true
在表格中包含动态类型
Flux 表格不支持动态类型。 要在 Flux 表格中包含动态值,请将动态类型转换为 Flux 基本类型。
以下示例使用array.from()
构建使用动态类型的临时表格。定义行记录时,每个动态类型都必须转换为 Flux 基本类型。
import "array"
import "experimental/dynamic"
dynamicString = dynamic.dynamic(v: "one")
dynamicInt = dynamic.dynamic(v: 1)
dynamicFloat = dynamic.dynamic(v: 1.0)
dynamicBool = dynamic.dynamic(v: true)
array.from(
rows: [
{
string: string(v: dynamicString),
int: int(v: dynamicInt),
float: float(v: dynamicFloat),
bool: bool(v: dynamicBool),
},
],
)
将 JSON 数组转换为 Flux 表格
导入以下包
使用
dynamic.jsonParse()
将从requests.get()
返回的 JSON 响应正文解析为 Flux 动态类型。定义一个变量以捕获已解析的 JSON。以下示例使用parsed
变量。使用
dynamic.asArray()
将dynamic.jsonParse()
返回的动态类型转换为动态数组。定义一个变量以捕获动态数组。以下示例使用fruit
变量。使用
array.map()
执行以下操作- 迭代动态数组中的每个动态记录,并展平嵌套记录。Flux 表格不支持嵌套记录(JSON 对象的推论)。
- 显式地将每个动态记录中的动态值转换为 Flux 基本类型。
以下示例使用http/requests
包和Fruityvice API 返回有关各种水果的 JSON 信息,然后将返回的数据结构化为 Flux 表格。
import "array"
import "experimental/dynamic"
import "http/requests"
response = requests.get(url: "https://www.fruityvice.com/api/fruit/all")
parsed = dynamic.jsonParse(data: response.body)
fruit = dynamic.asArray(v: parsed)
fruit_flat =
fruit
|> array.map(
fn: (x) =>
({
name: string(v: x.name),
cals: int(v: x.nutritions.calories),
carbs: float(v: x.nutritions.carbohydrates),
fat: float(v: x.nutritions.fat),
protein: float(v: x.nutritions.protein),
sugar: float(v: x.nutritions.sugar),
}),
)
array.from(rows: fruit_flat)
将动态类型编码为 JSON
将动态记录编码为 JSON
- 导入
experimental/dynamic
包。 - 使用
dynamic.dynamic()
将记录转换为动态类型。 - 使用
dynamic.jsonEncode()
将动态记录转换为字节编码的 JSON 字符串。
import "experimental/dynamic"
dynamicRecord = dynamic.dynamic(v: {one: 1, two: 2, three: 3})
dynamic.jsonEncode(v: dynamicRecord)
// Returns the following byte-encoded JSON string:
// {"one":1,"three":3,"two":2}
将不同基本类型的动态数组编码为 JSON
构建一个动态数组,其中每个元素都是不同的基本类型。如果您要将 JSON 数据发送到期望值数组(其中每个值都是不同类型)的 API,则这可能是必要的。Flux 数组中的值必须是相同的类型,因此您必须构建动态类型的动态数组
- 导入
experimental/dynamic
包。 - 使用
dynamic.dynamic()
将数组转换为动态类型。 - 使用
dynamic.dynamic()
将数组中的所有值转换为动态类型。 - 使用
dynamic.jsonEncode()
将动态数组转换为字节编码的 JSON 字符串。
import "experimental/dynamic"
arr =
dynamic.dynamic(
v: [
dynamic.dynamic(v: "three"),
dynamic.dynamic(v: 2),
dynamic.dynamic(v: true)
],
)
dynamic.jsonEncode(v: arr)
// Returns the following byte-encoded JSON string:
// ["three", 2, true]
此页内容对您有帮助吗?
感谢您的反馈!