Q for Mortals2笔记 -- 造型和枚举

本文深入探讨了Q语言中的类型系统,包括基本类型、变量类型、造型操作符的使用及其对不同类型转换的影响。文章详细解释了如何通过造型操作符实现数据类型的转换,并阐述了类型与造型在Q语言中的作用,特别强调了造型操作符在转换过程中的智能列表处理能力。同时,文章还介绍了如何利用造型操作符创建指定类型的空列表以及枚举的概念与应用,为读者提供了一个全面的理解与实践指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

类型和造型

基本类型

即原子类型

类型

可以用type来查看任意q实体的类型(用short数值类型表示),原子数的返回值都是负数,简单列表的返回值是正数(原子数的类型值跟其简单列表的类型值一样,只是正负数的差别)。普通列表的返回值是0h

q)type `42
-11h
q)type (`42;`a;`b)
11h
q)type (42;`42)
0h

变量的类型

在q里,不需要显示的声明变量的类型,变量的类型是它的值的类型,重新赋值后类型也会跟值类型变化而变化。

造型($)

$是一个二元操作符,右参是要被转换的原子数,左参是要转换到的类型,左参可以用以下四种方式:

  • 类型的短整型值,如整型是6h
  • 类型的字符值,如整型是"i"
  • 类型的名称符号,如整型是`int
q)6h$4.2
4i
q)"i"$4.2
4i
q)`int$4.2
4i

 $支持左右参数的智能列表处理

q)"b"$0 1 2
011b
q)5 6 7h$42
42h
42i
42
q)5 6 7h$4.2 5.2 6.2
4h
5i
6
q)5 6 7h$4.2 5.2
'length

将整数型的无穷数转换成更大范围的类型时,按它们的实际值处理,无穷数只是该类型的最大数,在更大范围的类型里,它也只是个普通值

q)"i"$0Wh
32767i
q)"j"$-0Wi
-2147483647

字符串、字符->符号

用空符号(`)来作为左参。对于包含空格和特殊字符的符号,无法使用直接定义的方式赋值,而是要通过符号->字符串的方式赋值。

q)`$"z"
`z
q)`$"Happy Birthday"
`Happy Birthday

 在转换的过程中,字符串的左右空白会被移除

q)`$"   abc "
`abc 

字符串->数据类型

使用大写的类型的字符名称

q)"I"$"4267"
4267i
q)"T"$"23:59:59.999"
23:59:59.999

 对于代表日期的字符串,可以支持不同的格式

q)"D"$"2007-04-24"
2007.04.24
q)"D"$"12/25/2006"
2006.12.25
q)"D"$"07/04/06"
2006.07.04 

Coercing Types

简单列表的子元素赋值不能更改其类型

q)c:10 20 30 40
q)c[1]:42h
'type

 我们可以使用列表的类型来转换值后再赋值

q)c[1]:(type c)$42h
q)c
10 42 30 40
q)c[0 1 3]:(type c)$(1.1;42j;0x21)
q)c
1 42 30 33

实际上type c=7h,跟我们指定7h作左参没有区别,只不过它是动态的,事先不需要知道它的类型。同样也可用于原子数,但是要将类型转换成正数,因为原子数的type返回值是负的

q)a:10
q)a:(type a)$10i
'type
q)a:(neg type a)$10i
q)a
10

创建指定类型的空列表

我们可以用()定义一个空列表,但是它是一个普通列表,没有指定任何子元素类型

q)type ()
0h

 我们可以使用造型来创建指定类型的空列表

q)type `int$()
6h
q)type `$()
11h

 当我们需要强制类型匹配的时候,指定类型的空列表很有用

q)L:`int$()
q)L,:4.2
'type
q)L,:4
q)L
,4i 

枚举

在造型时,左参是一个代表某种类型的字符型、短整型或者符号。在这一节里,造型将被扩展到用户定义的目标域,提供枚举类型的函数版本。

传统的枚举

传统的枚举的目的是:

  • 用一个描述性的名称代替含糊不清的数字,例如"blue"代替3
  • 强类型检查,保证只使用允许的值
  • 命名空间,同一个名字可以在不同的地方(代表不同的含义)使用而不会造成混淆

数据规范化

数据规范化可以减少重复并保留最少的数据量。例如,有一个文本列表,其文本来自一个固定的数量较少的文本集合,存储这个文本会带来如下问题:

  • 每个文本长度的不同使得列表的存储管理更复杂
  • 列表里很可能存在大量重复的文本

枚举可以解决以上问题。

q)v:`c`b`a`c`c`b`a`b`a`a`c
q)u:distinct v
q)u
`c`b`a
q)k:u?v
q)k
0 1 2 0 0 1 2 1 2 2 0
q)u[k]
`c`b`a`c`c`b`a`b`a`a`c
q)v~u[k]
1b

 u和k规范化了v。这样做的目的是空间压缩和速度。假定u的大小是a,u里的符号子元素的最大占用空间是b(个人疑问,不确定kdb+里是symbol列表按固定长度还是实际长度存储symbol?)。对于长度是x的v,其存储空间是

b*x
 而对于规范化后的u和k,存储空间是
a*b+4*x
 当x远大于a的时候,后者更节约空间。尤其是子元素占用空间很大的时候
q)v:`ccccccc`bbbbbbb`aaaaaaa`ccccccc`ccccccc`bbbbbbb
q)u:distinct v
q)u
`ccccccc`bbbbbbb`aaaaaaa
q)k:u?v
q)k
0 1 2 0 0 1
另外,从磁盘读写索引列表k是非常快的块操作。

枚举

枚举封装了上述的任意symbol列表的因子分解,其语法是

`u$v

 u是一个symbol类型的唯一列表,v是一个原子类型或者原子类型的列表。

使用枚举

定义枚举,实际上保存的是索引列表

q)u:`c`b`a
q)v:`c`b`a`c`c`b`a`b`a`a`a`c
q)ev:`u$v
q)ev
`u$`c`b`a`c`c`b`a`b`a`a`a`c

 使用枚举的时候就跟使用v一样

q)v[3]
`c
q)ev[3]
`u$`c
q)v[3]:`b
q)v
`c`b`a`b`c`b`a`b`a`a`a`c
q)ev[3]:`b
q)ev
`u$`c`b`a`b`c`b`a`b`a`a`a`c
q)v=`a
001000101110b
q)ev=`a
001000101110b
q)v in `a`b
011101111110b
q)ev in `a`b
011101111110b

 如果比较v和ev,=和~有不同的结果,=支持智能列表处理而~仅比较本身

q)v=ev
111111111111b
q)v~ev
0b 

更新枚举

在使用枚举的地方更新同一个值只需要一个操作就可以了,可以大大提高有很多重复的大列表的性能

q)u[1]:`x
q)ev
`u$`c`x`a`x`c`x`a`x`a`a`a`c
q)v
`c`b`a`b`c`b`a`b`a`a`a`c

 如果要在v上达到同样的效果,需要变更每个地方

q)v[where v=`b]:`x
q)v
`c`x`a`x`c`x`a`x`a`a`a`c

往枚举里添加新值

 往v里添加新值是一个简单的操作而在ev里则不一样,你不能直接添加一个新值(新值指的是不在u里面的值),必须先加到u里才能再加到ev里。但是我们往ev里加一个值的时候并不知道它是否是新值,这时候我们可以用?操作符来解决这个问题,该操作符只有在值不在列表里才会将值加入列表

q)u:`c`b`a
q)v:`c`b`a`c`c`b`a`b`a`a`a`c
q)ev:`u$v
q)v,:`d
q)v
`c`b`a`c`c`b`a`b`a`a`a`c`d
q)ev,:`d
'cast
q)u,:`d
q)ev,:`d
q)ev
`u$`c`b`a`c`c`b`a`b`a`a`a`c`d
q)u
`c`b`a`d
q)`u?`a
`u$`a
q)u
`c`b`a`d
q)`u?`e
`u$`e
q)u
`c`b`a`d`

还原枚举

可以使用value来还原枚举

q)u:`c`a`b
q)v:`c`b`a`c`c`b`a`b`a`a`a`c
q)ev:`u$v
q)ev
`u$`c`b`a`c`c`b`a`b`a`a`a`c
q)value ev
`c`b`a`c`c`b`a`b`a`a`a`c
q)v~value ev
1b 

枚举的类型

 每个枚举都会被授予一个新的从20开始的数字表示的类型

q)u1:`c`b`a
q)u2:`2`4`6`8
q)u3:`a`b`c
q)u4:`c`b`a
q)type `u1$`c`a`c`b`b`a
22h
q)type `u1$`a`a`b`b`c`c
22h
q)type `u4$`c`a`c`b`b`a
23h
q)type `u2$`8`8`4`2`6`4
24h
q)type `u3$`c`a`c`b`b`a
25h

 上面从22开始是因为前面已经有枚举了。基于同一个列表的枚举其类型相同,如上述代码里两个基于u1的枚举类型都是22,。另外枚举类型的数字顺序跟列表定义的顺序无关,跟定义枚举的顺序有关,例如u2在u4之前定义但是在u4之后应用于枚举,因此u4的枚举是23而u2的枚举是22。如果右参是一个原子类型,类型是负数

q)type `u1$`a
-22h

 注意,同一个值基于不同域的枚举是不一样的,即使它们的域是相等的

q)u1~u4
1b
q)v:`c`a`c`b`a
q)(`u1$v)~`u4$v
0b 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值