以下内容来自 尚硅谷,写这一系列的文章,主要是为了方便后续自己的查看,不用带着个PDF找来找去的,太麻烦!
第 5 章 FLUX中的数据类型
5.1 10 个基本数据类型
5.1.1 Boolean (布尔型)
5.1.1.1 将数据类型转换为boolean
1、使用bool( )函数可以将下述的 4 个基本数据类型转换为boolean:
类型 | 说明 |
---|---|
string(字符串) | 字符串必须是 “true” 或 “false” |
float(浮点数) | 值必须是 0 .0(false)或 1 .0(true) |
int(整数) | 值必须是 0 (false)或 1 (true) |
uint(无符号整数) | 值必须是 0 (false)或 1 (true) |
示例:
bool(v: "true")
// Returns true
bool(v: 0.0)
// Returns false
bool(v: 0)// Returns false (^)
bool(v: uint(v: 1))
// Returns true
5.1.2 bytes (字节)
1、注意是bytes(复数)不是byte,bytes类型表示一个由字节组成的序列。
5.1.2.1 定义bytes
1、FLUX没有提供关于bytes的语法。可以使用bytes函数将字符串转为bytes。
注意:只有字符串类型可以转换为bytes。
bytes(v:"hello")
// Returns [104 101 108 108 111]
5.1.2.2 将表示十六进制的字符串转为bytes
1、引入"contrib/bonitoo-io/hex"包
2、使用hex.bytes() 将表示十六进制的字符串转为bytes
import "contrib/bonitoo-io/hex"
hex.bytes(v: "FF5733")
// Returns [255 87 51] (bytes)
5.1.2.3 使用display( )函数获取bytes的字符串形式
1、使用display( )返回字节的字符串表示形式。bytes的字符串表示是 0 x开头的十六进制
表示。示例:
import "sampledata"
sampledata.string()
|> map(fn: (r) => ({r with _value: display(v: bytes(v:
r._value))}))
5.1.3 Duration持续时间
1、持续时间提供了纳秒级精度的时间长度。
5.1.3.1 持续时间的语法
缩写 | 说明 |
---|---|
ns | 纳秒 |
us | 微秒 |
ms | 毫秒 |
s | 秒 |
m | 分钟 |
h | 小时 |
d | 天 |
w | 周 |
mo | 日历月 |
y | 日历年 |
1、示例:
1ns // 1 纳秒
1us // 1 微妙
1ms // 1 毫秒
1s // 1 秒
1m // 1 分钟
1h // 1 小时
1d // 1 天
1w // 1 星期
1mo // 1 日历月
1y // 1 日历年
3d12h4m25s // 3天 12 小时 4 分钟又 25 秒
2、注意!持续时间的声明不要包含先导 0比如:
01m // 解析为整数 0 和 1 分钟的持续时间
02h05m //解析为整数 0 、 2 小时的持续时间,整数 0 和 5 分钟的持续时间。而不是 2小时又 5 分钟
5.1.3.2 将其他数据类型解释为持续时间
1、使用duration( )函数可以将以下基本数据类型转换为持续时间
2、字符串:将表示持续时间字符串的函数转换为持续时间。
3、int:将整数先解释为纳秒再转换为持续时间
4、unit:将整数先解释为纳秒再转换为持续时间。
duration(v: "1h30m")
// Returns 1h30m
duration(v: 1000000)
// Returns 1ms
duration(v: uint(v: 3000000000))
// Returns 3s
注意!你可以在FLUX语言中使用duration类型的变量与时间做运算,但是你不能在table中创建duration类型的列。
5.1.3.3 duration的算术运算
1、要对duration进行加法、减法、乘法或除法操作,需要按下面的步骤来。
- 使用int( )或unit()将持续时间转换为int数值
- 使用算术运算符进行运算
- 把运算的结果再转换回Duration类型
2、示例:
duration(v: int(v: 6h4m) + int(v: 22h32s))
// 返回 1d4h4m32s
duration(v: int(v: 22h32s) - int(v: 6h4m))
// 返回 15h56m32s
duration(v: int(v: 32m10s) * 10)
// 返回 5h21m40s
duration(v: int(v: 24h) / 2)
// 返回 12h
注意!声明持续时间的时候不要包含前导 0 ,前面的零会被FLUX识别为整数
5.1.3.4 时间和持续时间相加运算
1、导入date包
2、使用date.add( )函数将持续时间和时间相加
3、示例:
import "date"
date.add(d: 1w, to: 2021 - 01 - 01T00:00:00Z)
// 2021- 01 - 01 加上一周
// Returns 2021- 01 - 08T00:00:00.000000000Z
5.1.3.5 时间和持续时间相减运算
1、导入date包
2、使用date.add( )函数从时间中减去持续时间
3、示例:
import "date"
date.sub(d: 1w, from: 2021- 01 - 01T00:00:00Z)
// 2021- 01 - 01 减去一周
// Returns 2020- 12 - 25T00:00:00.000000000Z
5.1.4 Regular expression 正则表达式
5.1.4.1 定义一个正则表达式
1、 FLUX语言是GO语言实现的,因此使用GO的正则表达式语法。正则表达式需要声明在正斜杠之间 / /
5.1.4.2 使用正则表达式进行逻辑判断
1、使用正则表达式进行逻辑判断,需要使用 =~ 和 != 操作符。=~ 的意思是左值(字符串)能够被右值匹配,!~表示左值(字符串)不能被右值匹配。
"abc" =~ /\w/
// Returns true
"z09se89" =~ /^[a-z0-9]{7}$/
// Returns true
"foo" !~ /^f/
// Returns false
"FOO" =~ /(?i)foo/
// Returns true
5.1.4.3 将字符串转为正则表达式
1、引入regexp包
2、使用regexp.compile( ) 函数可以将字符串转为正则表达式
import "regexp"
regexp.compile(v: "^// Returns ^- [a-z0--9]{7} (regexp type) [a-z0-9]{7}") (^)
5.1.4.4 将匹配的子字符串全部替换
1、引入regexp包
2、使用regexp.replaceAllString( )函数,并提供下列参数:
- r:正则表达式
- v:要搜索的字符串
- t: 一旦匹配,就替换为该字符串
3、示例:
import "regexp"
regexp.replaceAllString(r: /a(x*)b/, v: "-ab-axxb-", t: "T")
// Returns "-T-T-"
5.1.4.5 得到字符串中第一个匹配成功的结果
1、导入regexp包
2、使用 regexp.findString( )来返回正则表达式匹配中的第一个字符串,需要传递以下参数:
- r:正则表达式
- v:要进行匹配的字符串
3、示例:
import "regexp"
regexp.findString(r:"abc|bcd",v:"xxabcwwed")
// Returns "abc"
5.1.5 String 字符串
5.1.5.1 定义一个字符串
1、字符串类型表示一个字符序列。字符串是不可改变的,一旦创建就无法修改。
2、字符串是一个由双引号括起来的字符序列,在FLUX中,还支持你用\x作为前缀的十六进制编码来声明字符串。
3、示例:
"abc"
"string with double " quote"
"string with backslash \"
"日本語"
"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"
5.1.5.2 将其他基本数据类型转换为字符串
1、使用srting( )函数可以将下述基本类型转换为字符串:
- boolean 布尔值
- bytes 字节序列
- duration 持续时间
- float 浮点数
- uint 无符号整数
- time 时间
string(v: 42)
// 返回 "42"
5.1.5.3 将正则表达式转换为字符串
1、因为正则表达式也是一个基本数据类型,所以正则表达式也可以转换为字符串,但是需要借助额外的包。
- 引入regexp包
- 使用regexp.compile( )
5.1.6 Time 时间点
5.1.6.1 定义一个时间点
1、一个time类型的变量其实是一个纳秒精度的时间点。
2、示例:
时间点必须使用RFC3339的时间格式进行声明
YYYY-MM-DD
YYYY-MM-DDT00:00:00Z
YYYY-MM-DDT00:00:00.000Z
5.1.6.2 date包
1、date包里的函数主要是用来从Time类型的值里提取年月日秒等信息的。比如date.hour:
import "date"
x = 2020-01-01T19:22:31Z
date.hour(t:x)
//Returns 19
5.1.7 Float 浮点数
5.1.7.1 定义一个浮点数
1、FLUX中的浮点数是 64 位的浮点数。
2、一个浮点数包含整数位,小数点,和小数位。
3、示例:
0.0
123.4
-123.456
5.1.7.2 科学计数法
1、FLUX没有直接提供科学计数法语法,但是你可以使用字符换写出一个科学计数法表示的浮点数,再使用float( )函数将该字符串转换为浮点数。
2、示例:
1.23456e+78
// Error: error @1:8-1:9: undefined identifier e
float(v: "1.23456e+78")
// Returns 1.23456e+78 (float)
5.1.7.3 无限
1、FLUX也没有提供关于无限的语法,定义无限要使用字符串与float( )函数结合的方式。
2、示例:
+Inf
// Error: error @1:2-1:5: undefined identifier Inf
float(v: "+Inf")
// Returns +Inf (float)
5.1.7.4 Not a Number 非数字
1、FLUX语言不支持直接从语法上声明NAN,但是你可以使用字符串与float( )函数的方法声明一个NaN的float类型变量。
2、示例:
NaN
// Error: error @1:2-1:5: undefined identifier NaN
float(v: "NaN")// Returns NaN (float) (^)
5.1.7.5 将其他基本类型转换为float
1、使用float函数可以将基本数据类型转换为float类型的值。
类型 | 说明 |
---|---|
string | 必须得是一个符合数字格式的字符串或者科学计数法。 |
bool | true转换为 1 .0,false转换为 0 .0 |
int | (整数) |
uint | (无符号整数) |
2、示例:
float(v: "1.23")
// 1.23
float(v: true)
// Returns 1.0
float(v: 123)
// Returns 123.0
5.1.7.6 对浮点数进行逻辑判断
1、使用FLUX表达式来比较浮点数。逻辑表达式两侧必须是同一种类型。
2、示例:
12345600.0 == float(v: "1.23456e+07")// Returns true
1.2 > -2.1
// Returns true
5.1.8 Integer 整数
5.1.8.1 定义一个整数
1、一个integer的变量是一个 64 位有符号的整数。
2、类型名称:int
- 最小值:- 9223372036854775808
- 最大值: 9223372036854775807
3、一个整数的声明就是普通的整数写法,前面可以加 - 表示负数。- 0 和 0 是等效的。
4、示例:
0
2
1254
- 1254
5.1.8.2 将数据类型转换为整数
1、使用int( )函数可以将下述的基本类型转换为整数:
类型 | 说明 |
---|---|
string | 字符串必须符合整数格式,由数字[ 0 - 9]组成 |
bool | true返回 1 , 0 返回false |
duration | 返回持续时间的纳秒数 |
time | 返回时间点对应的Unix时间戳纳秒数 |
float | 返回小数点前的整数部分,也就是截断 |
unit | 返回等效于无符号整数的整数,如果超出范围,就会发生整数环绕 |
int(v: "123")// 123
int(v: true)
// Returns 1
int(v: 1d3h24m)
// Returns 98640000000000
int(v: 2021// Returns 1609459200000000000- 01 - 01T00:00:00Z) (^)
int(v: 12.54)
// Returns 12
2、你可以在将浮点数转换为整数之前进行舍入操作。当你将浮点数转换为整数时,会进行截断操作。如果你想进行四舍五入,可以使用math包中的round( )函数。
5.1.8.3 将表示十六进制数字的字符串转换为整数
将表示十六进制数字的字符串转换为整数,需要。
- 引入contrib/bonito-io/hex包
- 使用hex.int( )函数将表示十六进制数字的字符串转换为整数
import "contrib/bonitoo-io/hex"
hex.int(v: "e240")
// Returns 123456
5.1.9 UIntegers 无符号整数
1、FLUX语言里不能直接声明无符号整数,但这却是一个 InfluxDB中具备的类型。在FLUX语言中,我们需要使用uint函数来讲字符串、整数或者其他数据类型转换成无符号整数。
2、示例:
uint(v: "123")
// 123
uint(v: true)
// Returns 1
uint(v: 1d3h24m)
// Returns 98640000000000
uint(v: 2021- 01 - 01T00:00:00Z)
// Returns 1609459200000000000
uint(v: 12.54)
// Returns 12
uint(v: -54321)
// Returns 18446744073709497295
5.1.10 Null 空值
5.1.10.1 定义一个Null值
1、FLUX语言并不能在语法上直接支持声明一个Null,但是我们可以通过debug.null这个函数来声明一个指定类型的空值。
2、示例:
import "internal/debug"
// Return a null string
debug.null(type: "string")
// Return a null integer
debug.null(type: "int")
// Return a null booleandebug.null(type: "bool")
5.1.10.2 定义一个null
1、截至目前,还无法在FLUX语言中手动地声明一个NULL值。
注意!空字符串不是null值
5.1.10.3 判断值是否为null
1、你可以使用exists(存在)这个关键字来判断目标值是不是非空,如果是空值我们会得到一个false,如果不是空值我们会得到一个true。
2、示例:
import "array"
import "internal/debug"
x = debug.null(type: "string")
y = exists x
// Returns false
5.1.11 正则表达式类型
1、正则表达式在FLUX中作为一种数据类型,而且在语法上提供直接的支持,可以在谓词表达式中使用正则表达式。
2、 示例:
regex = /^foo/
"foo" =~ regex
// Returns true
"bar" =~ regex
// Returns false
5.1.12 display函数
1、使用display( )函数可以将任何类型的值输出为相应的字符串类型。
2、示例:
x = bytes(v: "foo")
display(v: x)
// Returns "0x666f6f"
5.2 FLUX类型不代表InfluxDB类型
1、需要注意,FLUX语言里有些基本数据类型比如持续时间(Duration)和正则表达式是不能放在表流里面充当字段类型的。简单来说,Duration类型和正则表达式类型都是FLUX语言特有的。有些类型是为了让 FLUX在编写代码时更加方便,让它能够拥有更多的特性,但这并不代表这些类型能够存储到InfluxDB中。
5.3 4 个复合类型
5.3.1 Record(记录)
5.3.1.1 定义一个Record
1、一个记录是一堆键值对的集合,其中键必须是字符串,值可以是任意类型,在键上没有空白字符的前提下,键上的双引号可以省略。在语法上,record需要使用{}声明,键值对之间使用英文逗号(,)分开。另外,一个Record的内容可以为空,也就是里面没有键值对。
2、示例:
{foo: "bar", baz: 123.4, quz: -2}
{"Company Name": "ACME", "Street Address": "123 Main St.", id:1123445}
5.3.1.2 从record中取值
1、点表示法 取值 ,如果key中没有空白字符,那么你可以使用 .key 的方式从record中取值。
示例:
c = {name: "John Doe", address: "123 Main St.", id: 1123445}
c.name
/ / Returns John Doe
c.id
// Returns 1123445
2 、 中括号方式取值,可以使用[" "]的方式取值,当key中有空白字符的时候,也只能用这种方式来取值。
c = {"Company Name": "ACME", "Street Address": "123 Main St.", id:
1123445}
c["Company Name"]
// Returns ACME
c["id"]
// Returns 1123445
5.3.1.3 嵌套与链式取值
1、Record类型可以进行嵌套引用。从嵌套的Record中引用值的时候可以采用链式调用的方式。链式调用时,点表示法和中括号还可以混用。
5.3.1.4 record的key是静态的
1、record类型变量中的key是静态的,一旦声明,其中的key就被定死了。一旦你访问这个record中一个没有的key,就会直接抛出异常。正常的话应该返回null。
o = {foo: "bar", baz: 123.4}
o.key
// Error: type error: record is missing label haha
// 错误:类型错误:record找不到haha 这个标签
5.3.1.5 操作records
1、拓展一个record使用 with 操作符可以拓展一个record,当原始的record中有这个key时,原先record的值会被覆盖;如果原先的record中没有制定的key,那么会将旧record中的所有元素和with中指定的元素复制到一个新的record中。
2、示例: 覆盖原先的值,并添加一个key为pet,value为"Spot"的元素。
c = {name: "John Doe", id: 1123445}
{c with name: "Xiao Ming", pet: "Spot"}
// Returns {id: 1123445, name: Xiao Ming, pet: Spot}
5.3.1.6 列出一个record中所有的keys
1、导入experimental(实验的)包。
2、使用expertimental.objectyKeys(o:c)方法来拿到一个record的所有key。
3、示例:
import "experimental"
c = {name: "John Doe", id: 1123445}
experimental.objectKeys(o: c)
// Returns [name, id]
5.3.1.7 比较两个record是否相等
1、可以使用双等号= =来判断两个record是否相等。如果两个 record的每个key,每个key对应的value和类型都相同,那么两个record就相等。
2、示例:
{id: 1, msg: "hello"} == {id: 1, msg: "goodbye"}
// Re turns false
{foo: 12300.0, bar: 34500.0} == {bar: float(v: "3.45e+04"), foo:
float(v: "1.23e+04")}
// Returns true
5.3.1.8 将record转为字符串
1、使用display( )函数可以将record转为字符串。
2、示例:
x = {a: 1, b: 2, c: 3}
display(v: x)
// Returns "{a: 1, b: 2, c: 3}"
5.3.1.9 嵌套Record的意义
1、注意,嵌套的Record无法放到FLUX语言返回的表流中,这个时候会发生类型错误,它会说Record类型不能充当某一列的类型。那FLUX为什么还支持对Record进行嵌套使用呢?其实这是为了一些网络通讯的功能来服务,在FLUX语言中我们有一个http库。借助这个函数库,我们可以向外发送 http post请求,而这种时候我们就有可能要发送嵌套的json。细心的同学可能发现,我们的 record在语法层面上和 json语法是统一的,而且FLUX语言提供了一个json函数库,借助这个库中的encode函数,我们可以轻易地将一个record转为json字符串然后发送出去。
5.3.2 Array(数组)
5.3.2.1 定义一个Array
1、数据是一个由相同类型的值构成的有序序列。 在语法上,数组是用方括号[ ]起来的一堆同类型元素,元素之间用英文逗号( , )分隔,并且类型必须相同。
2、示例:
["1st", "2nd", "3rd"]
[1.23, 4.56, 7.89]
[10, 25, -15]
5.3.2.2 从Array中取值
1、可以使用中括号 [ ] 加索引的方式从数组中取值,数组索引从 0 开始。
2、示例:
arr = ["one", "two", "three"]
arr[0]
// Returns one
arr[2]
// Returns two
5.3.2.3 遍历一个数组
5.3.2.4 检查一个数组中是否包含某元素
1、示例
2、使用contains( )函数可以检查一个数组中是否包含某个元素。
names = ["John", "Jane", "Joe", "Sam"]
contains(value: "Joe", set: names)
// Returns true
5.3.3 Dictionary(字典)
5.3.3.1 定义一个字典
1、字典和记录很像,但是key-value上的要求有所不同。一个字典是一堆键值对的集合,其中所有键的类型必须相同,且所有值的的类型必须相同。在语法上,dictionary需要使用方括号[ ]声明,键的后面跟冒号(:)键值对之间需要使用英文逗号( , )分隔。
2、示例:
[0: "Sun", 1: "Mon", 2: "Tue"]
["red": "#FF0000", "green": "#00FF00", "blue": "#0000FF"]
[1.0: {stable: 12, latest: 12}, 1.1: {stable: 3, latest: 15}]
5.3.3.2 引用字典中的值
1、导入dict包
2、使用dict.get( )并提供下述参数:
- dict:要取值的字典
- key:要用到的key
- default:默认值,如果对应的key不存在就返回该值
3、示例
import "dict"
positions =
[
"Manager": "Jane Doe",
"Asst. Manager": "Jack Smith",
"Clerk": "John Doe",
]
dict.get(dict: positions, key: "Manager", default: "Unknown
position")
// Returns Jane Doe
dict.get(dict: positions, key: "Teller", default: "Unknown
position")
// Returns Unknown position
5.3.3.3 从列表创建字典
1、导入dict包
2、使用dict.fromList( )函数从一个由records组成的数组中创建字典。其中,数组中的每个record必须是{key:xxx,value:xxx}形式
3、示例:
import "dict"
list = [{key: "k1", value: "v1"}, {key: "k2", value: "v2"}]
dict.fromList(pairs: list)
// Returns [k1: v1, k2: v2]
5.3.3.4 向字典中插入键值对
1、导入dict包
2、使用dict.insert( )函数添加一个新的键值对,如果key早就存在,那么就会覆盖这个key对应的value。
3、示例:
import "dict"
exampleDict = ["k1": "v1", "k2": "v2"]
dict.insert(dict: exampleDict, key: "k3", value: "v3")// Returns [k1: v1, k2: v2, k3: v3]
5.3.3.5 从字典中移除键值对
1、引入dict包
2、使用dict.remove方法从字典中删除一个键值对
3、示例:
import "dict"
exampleDict = ["k1": "v1", "k2": "v2"]
dict.remove(dict: exampleDict, key: "k2")
// Returns [k1: v1]
5.3.4 function(函数)
5.3.4.1 声明一个函数
1、一个函数是使用一组参数来执行操作的代码块。函数可以是命名的,也可以是匿名的。
2、在小括号( )中声明参数,并使用箭头=>将参数传递到代码块中。
3、 示例:
square = (n) => n * n
square(n:3)
// Returns 9
FLUX不支持位置参数。调用函数时,必须显示指定参数名称。
5.3.4.2 为函数提供默认值
1、我们可以为某些函数指定默认值,如果为函数指定了默认值,也就意味着在调用这个函数时,有默认值的函数时非必须的。
2、示例:
chengfa = (a,b=100) => a* b
chengfa(a:3)
// Returns 300
5.4 函数包
1、Flux的标准库使用包组织起来的。包将Flux的众多函数分门别类,默认情况下加载universe包,这个包中的函数可以不用import直接使用。其他包的函数需要在你的Flux脚本中先用import语法导入一下。
2、示例:
import "array"
import "math"
import "influxdata/influxdb/sample"
3、但是,截至目前,虽然你可以自定义函数,但是你无法自定义包。如果希望将自己的
自定义函数封装在一个包里以供复用,那就必须从源码上进行修改。