1. 类型
1. 基础数据类型
2. type 操作符 type 操作符返回一个 short,并且如果对象是一个 atom,则返回负数;是一个 list 则返回正数。
q)type 42
-7h
q)type 10 20 30
7h
q)type 98.6
-9h
q)type 1.1 2.2 3.3
9h
q)type `a
-11h
q)type `a`b`c
11h
q)type “z”
-10h
q)type “abc”
10h
任何常规列表 (general list) 的类型都是 0h。
q)type (42h; 42i; 42j)
0h
q)type (1 2 3; 10 20 30)
0h
q)type ()
0h
任何字典 (包括键表) 的类型,都是 99h。
q)type (`a`b`c!10 20 30)
99h
q)type ([k:`a`b`c] v:10 20 30)
99h
任何表的类型都是 98h。
q)type ([] c1:`a`b`c; c2:10 20 30)
98h
3. 变量的类型 q 语言是动态类型语言,所以变量的类型也会随着其被赋的值而改变。
全局变量会被储存在一个一般的 q 字典中。可以通过命令 get `. 来查看全局变量和对应的值,也可以通过操作符 value 来查看
q)value `.
q)a:42
q)value `.
a| 42
q)f:{x*x}
q)value `.
a| 42
f| {x*x}
..
2. Cast
转换使用 dyadic 操作符 $,右边的运算元是原始值,而左边的运算元是目标类型。有三种方式指定目标类型:
数值的 short 类型
char 类型值
类型的 symbol 名称
1. Casts that Widen 因为目标类型比原始类型要宽,所以在这种情况下没有信息丢失。
q)7h$42i / int to long
42
q)6h$42 / long to int
42i
q)9h$42 / long to float
42f
q)”j”$42i
42
q)”i”$42
42i
q)”f”$42
42f
more readable:
q)`int$42
42i
q)`long$42i
42
q)`float$42
42f
2. 不同类型之间的转换 char 类型的 underlying value 是 ASCII 码,所以我们可以将 char 与 integer 互相转换。
q)`char$42
“*”
q)`long$”\n”
10
同样,也可以将日期与 integer 互相转换
q)`date$0
2000.01.01
q)`int$2001.01.01 / millennium occurred on leap year
366i
3. Casts that Narrow
q)`long$12.345
12
q)`short$123456789
32767h
将数值类型转换为 boolean 类型,任何 0 值都是 0b,其余的值都是 1b。
q)`boolean$0
0b
q)`boolean$0.0
0b
q)`boolean$123
1b
q)`boolean$-12.345
1b
也可以从复杂类型中提取成分
q)`date$2015.01.02D10:20:30.123456789
2015.01.02
q)`year$2015.01.02
2015i
q)`month$2015.01.02
2015.01m
q)`mm$2015.01.02
1i
q)`dd$2015.01.02
2i
q)`hh$10:20:30.123456789
10i
q)`minute$10:20:30.123456789
10:20
q)`uu$10:20:30.123456789
20i
q)`second$10:20:30.123456789
10:20:30
q)`ss$10:20:30.123456789
30i
4. Casting Integral Inf
q)`int$0Wh
32767i
q)`int$-0Wh
-32767i
q)`long$0Wi
2147483647
q)`long$-0Wi
-2147483647
5. 强制类型回想在向一个简单列表中赋值的时候需要严格 match 列表的类型
q)L:10 20 30 40
q)L[1]:42h
‘type
q)L,:43h
‘type
这种情况可以通过强制类型转换来实现:
q)L[1]:(type L)$42h
q)L,:(type L)$43h
6. Cast is Atomiccast 对其右运算元是 atomic 的:
q)”i”$10 20 30
10 20 30i
q)`float$(42j; 42i; 42j)
42 42 42f
cast 对其左运算元也是 atomic 的:
q)`short`int`long$42
42h
42i
42
q)”ijf”$98.6
99i
99
98.6
Cast 对左右运算元同步的 atomic:
q)”ijf”$10 20 30
10i
20
30f
3. 数据和文本的转换
1. 数据转换为 string 使用函数 string 可以将任何 q 元素转换为一个合适的文本表示。string 的一些特征:
转换结果是一个 char 的列表,不会是单个的 char。
转换结果不会包含任何 q 类型提示符或者其它装饰符。
string 作用在一个真正的 string(list of char)上可能不会得到你想要的结果
q)string 42
“42”
q)string 4
,”4″
q)string 42i
“42”
q)a:2.0
q)string a
,”2″
q)f:{x*x}
q)string f
“{x*x}”
string 是伪 atomic 的,它会作用在运算元的每个 atom 数据上,但对每个 atom 元素的运算结果都返回一个 list
q)string 1 2 3
,”1″
,”2″
,”3″
q)string “string”
,”s”
,”t”
,”r”
,”i”
,”n”
,”g”
q)string (1 2 3; 10 20 30)
,”1″ ,”2″ ,”3″
“10” “20” “30”
2. 从 String 构建 Symbol 从 string 去创建 symbol 是一个 foolproof 的做法。但是也是唯一的去创建带有空格或者其它特殊符号 symbol 的方法。其转换使用 `$。
q)`$”abc”
`abc
q
q)`$”Hello World”
`Hello World
注意带有转义符的转换:
q)`$”Zaphod \”Z\””
`Zaphod “Z”
q)`$”Zaphod \n”
`Zaphod
Note: 左右去空格。
q)string `$” abc ”
“abc”
3. 从 String 中解析数据使用大写的目标类型作为左运算元,string 作为右运算元。
q)”J”$”42″
42
q)”F”$”42″
42f
q)”F”$”42.0″
42f
q)”I”$”42.0″
0Ni
q)”I”$” ”
0Ni
日期转换:
q)”D”$”12.31.2014″
2014.12.31
q)”D”$”12-31-2014″
2014.12.31
q)”D”$”12/31/2014″
2014.12.31
q)”D”$”12/1/2014″
2014.12.31
q)”D”$”2014/12/31″
2014.12.31
可以从字符串中解析一个函数,使用内置的函数 value 或者 parse
q)value “{x*x}”
{x*x}
q)parse “{x*x}”
{x*x}
4. 创建带类型的空 list
空的 list 的类型是 0h,但是当 append 一个元素之后,得到的 sigleton 列表就是该元素类型的简单列表。
q)L:()
q)type L
0h
q)L,:42
q)type L
7h
如果想规定空 list 的类型,可以使用类似如下语法
q)c1:`float$()
q)c1,:42
‘type
q)c1:98.6
同样,下面的操作也能产生带类型的空 list
q)0#0
`long$()
q)0#0.0
`float$()
q)0#`
`symbol$()
5. Enumerations
1. 传统的枚举
In traditional languages, an enumerated type is a way of associating a series of names with a corresponding set of integral values.
2. 数据标准化
q)u:`g`aapl`msft`ibm
q)v:1000000?u
q)k:u?v
q)k
2 1 1 3 3 1 0 0 0 3 0 2 2 1 2 3 1 0 1 1 2 1 2 0 2 1 1 0 1 1 3 0..
上述关系满足映射:v=u*k,使用 u 和索引 k 来储存 v 可以大大节省储存空间,并且提高查找效率。
3. Enumerating Symbols 将一个 symbols 列表转换为对应的索引列表的操作称为 q 中的枚举。它以 $(又一重载)作为运算符,使用 unique 的 symbols 变量作为左运算元,在变量域的 symbol 的列表作为右运算元。
q)`u$v
`u$`msft`aapl`aapl`ibm`ibm`aapl`g`g`g`ibm`g`msft`msft`aapl`msft..
可以通过强制转换为 int 来恢复上述的索引结果
q)ev:`u$v
q)`int$ev
2 1 1 3 3 1 0 0 0 3 0 2 2 1 2 3 1 0 1 1 2 1 2 0 2 1 1 0 1 1 3 ..
枚举 symbol 的基本形式为:`u$v 其中 u 是 unique symbol 的简单列表,v 是在 u 中出现的 atom 或者对应的列表。我们称 u 为枚举的域(domain),投影 `u$ 为在 u 上的枚举。应用枚举 `u$ 在向量 v 上可以得到索引列表 k。
4. 使用枚举的 symbol
q)sym:`g`aapl`msft`ibm
q)v:1000000?sym
q)ev:`sym$v
枚举的 ev 可以在几乎所有的场景中代替 v。
q)v[3]
`aapl
q)ev[3]
`u$`aapl
q)v[3]:`ibm
q)ev[3]:`ibm
q)v=`ibm
000100010010011101000010010100000000100100000001000000001100001001011..
q)ev=`ibm
000100010010011101000010010100000000100100000001000000001100001001011..
q)where v=`aapl
4 5 19 20 21 31 33 34 41 42 43 49 58 59 61 74 81 83 90 94 95 98 114..
q)where ev=`aapl
4 5 19 20 21 31 33 34 41 42 43 49 58 59 61 74 81 83 90 94 95 98 114..
q)v?`aapl
4
q)ev?`aapl
4
q)v in `ibm`aapl
000111010010011101011110010100010110100101110001010000001111011001011..
q)ev in `ibm`aapl
000111010010011101011110010100010110100101110001010000001111011001011..
尽管枚举和原始列表是 item-wise 的相等,但是他们并不 identical(不 match)
q)all v=ev
1b
q)v~ev
0b
5. 枚举的类型每一个枚举都会被赋予一个新的数值类的数据类型,从 20h 开始。20h 是留给系统的枚举域的,你自己定义的枚举类型则从 21h 开始,并且逐个增加。类型的正号为 simple list,负号为 atom 的性质依旧保持。
q)sym1:`g`aapl`msft`ibm
q)type `sym1$1000000?sym1
21h
q)sym2:`a`b`c
q)type `sym2$`c
-22h
从不同域创建的枚举是不同的,即使他们的组成都相同
q)sym1:`c`b`a
q)sym2:`c`b`a
q)ev1:`sym1$`a`b`a`c`a
q)ev2:`sym2$`a`b`a`c`a
q)ev1=ev2
11111b
q)ev1~ev2
0b
6. 更新一个枚举的列表一个对 u 简单的改变,可以改变枚举 v 中对应的所有内容
q)sym:`g`aapl`msft`ibm
q)ev:`sym$`g`g`msft`ibm`aapl`aapl`msft`ibm`msft`g`ibm`g..
q)sym[0]:`twit
q)sym
`twit`aapl`msft`ibm
q)ev
`sym$`twit`twit`msft`ibm`aapl`aapl`msft`ibm`msft`twit`ibm`twit..
相反,则需要对 v 的每一处进行更新
q)v
`g`g`msft`ibm`aapl`aapl`msft`ibm`msft`g`ibm`g…
q)@[v; where v=`g; :; `twit]
7. 动态向枚举域添加直接向枚举 append 一个域中没出现过的元素时会报错
q)sym:`g`aapl`msft`ibm
q)v:1000000?sym
q)ev:`sym$v
q)v,:`twtr
q)ev,:`twtr
‘cast
正确做法是这个新值必须要先添加进域中
q)sym,:`twtr
q)ev,:`twtr
如果提前不知道域中的全部值,可以使用?(又一重载)来创建一个动态的域。? 的语法与枚举重载符 $ 的语法一样。unique 的 symbol list 的名字作为左运算元,源 symbol 列表作为右运算元。
q)sym:()
q)`sym$`g
‘cast
q)`sym?`g
`sym$`g
q)sym
,`g
q)`sym?`ibm`aapl
`sym$`ibm`aapl
q)sym
`g`ibm`aapl
q)`sym?`g`msft
`sym$`g`msft
q)sym
`g`ibm`aapl`msft
8. 恢复一个枚举可以通过 value 来恢复一个枚举对应的源 symbol 列表
q)sym:`g`aapl`msft`ibm
q)v:1000000?sym
q)ev:`sym$v
q)value ev
`aapl`g`msft`msft`ibm`msft`msft`msft`msft`msft`g`ibm`ibm`ibm..
q)v~value ev
1b