参数化类型(TypeParam)¶
参数化类型¶
MirrorQL允许将类型作为谓词、类、模块的参数使用,从而实现类似泛型的功能。
用示例说明参数化类型的用法。假设需要实现一个判断相等的谓词,一种可能的写法如下:
但isEqu谓词只能判断两个整数是否相等,无法判断两个字符串是否相等,若要判断,就要编写一个新的以str作为参数类型的谓词。
在isEqu谓词中,我们希望能处理所有类型相同的x和y,且不关心x和y具体是什么类型(只要两者类型相同即可)。
此时,可以考虑将isEqu的参数类型作为一个新的参数T。
要使用isEqu,需要给出T:x y两个参数的类型,x:T:参数1,y:T:参数2。
基于参数化类型的isEqu实现如下,可以处理任意类型的相等判断。
T在代码中代表某一个未知的类型。
类型约束¶
再考虑一个新谓词appendStr,将参数1转换为字符串后再向结尾添加"test"并返回。类似的,可以用参数化类型写出一个实现(但这个实现是错误的)
参数x的类型为T,编译器无法确定类型T是否有toString谓词,因此在类型检查时会报错。
此时需要对T增加类型约束,要求类型T必须实现asStr trait(也就是有toString成员谓词),新的写法为:
若类型约束包含多个trait,可用加号分隔:
也可以指定多个类型参数:
参数化谓词¶
参数化谓词的声明¶
要给谓词指定类型参数列表,只需要在谓词名后附加类型参数列表即可。例如谓词appendStr的类型参数列表为[T <: asStr]。
参数化谓词的使用¶
使用参数化谓词时,可以显式给出类型参数:
fn appendStr[T <: asStr] (x:T) -> str {
result == x.toString() + "test"
}
fn main(){
// 给出类型参数
appendStr[str] ("foo") == "footest"
}
编译器也可推导部分类型参数:
fn appendStr[T <: asStr] (x:T) -> str {
result == x.toString() + "test"
}
fn main(){
// 编译器推导 T = str
appendStr("foo") == "footest"
}
参数化类¶
Warning
参数化类在原版spec中并非标准实现,此处仅说明语法,不规定实现细节
与参数化谓词类似,参数化类的类型参数列表在1class1名后给出。使用参数化类时,在类名后给出类型参数列表。
class SomeClass [T <: asInt] extends int {
fn init(){
self == range(1,10)
}
fn get(x:T) -> int{
result == self + x.toInt()
}
}
fn main() {
// 类名后给出类型参数列表
let x:SomeClass[int];
x.get(1) == 2
}
参数化模块¶
参数化模块的声明¶
在模块名后给出类型参数列表即可声明参数化模块:
参数化模块的实例化¶
要使用参数化模块,需要首先给出类型参数列表,称为实例化。与参数化谓词和参数化类不同,参数化模块不能直接使用,不支持参数化模块。
要使用参数化模块,需要用到use module ... as ...语法。
举例说明如何实例化SomeMod