初探模板
请确保自己了解过模板或泛型后阅读。
在函数中使用模板
1 | // 模板类型名随意,但是建议符合struct/enum命名规则 |
好了,现在你可以对任意类型的数据使用test(t: T)
了:
1 | fn main() { |
但是上面的模板函数对参数没有做任何操作呢,不妨试试进行运算:
1 | fn test<T>(t: T) { |
尝试编译一下,肯定会报错:
1 | error[E0369]: cannot add `{integer}` to `T` |
肯定有人会想:上面的代码之所以报错,是因为对char
、array
类型使用了test(t: T)
而test(t: T)
又对t
使用了+
运算,因而无法编译。这个答案放在C++中是对的,但是放在Rust中则是错的。看看上面的报错原因error[E0369]: cannot add `{integer}` to `T`
(不能将属于{integer}
的类型加到T
上),错误发生在函数上而非类型上。简单的解释是:模板类型T
没有实现+
运算函数,即使对实现了+
运算函数的类型使用test(t: T)
,也不能编译。意味着,test(t: T)
和main()
里的4行语句都无法编译。
那么,如何让模板类型T
实现+
运算函数呢?
Rust中,并不能为模板类型T
实现+
,但是可以要求使用该函数的类型必须实现+
,并自己给调用该函数的类型实现+
,这样编译器就能确保使用该函数的类型都有+
运算。而报错的help
信息中提示了相关做法:
1 | help: consider restricting type parameter `T` |
让我们先尝试添加上述代码,你会发现,代码依然无法编译,因为{integer}
并不是可编译的类型,{integer}
是整型类型的统称,包括i8
、u8
...而且,如果你尝试将{integer}
改成u8
或i8
之类的整型,代码依然无法编译,具体的原因和解决办法脱离了主题,这里就不细说了,有兴趣的可以在学过下一篇后尝试实现。
回到正题,:
是修饰符,表示其前边的模板类型实现了后面列出的trait
,std::ops::Add<Output>
就是一个trait
。至于什么是trait
,下篇再详细介绍。
在struct
中使用模板
例子:
1 | struct Test<A, B> { |
在impl
中使用模板
例子:
1 | struct Test<A, B> { |