/*
fn max(array: &[i32]) -> i32 {
let mut max_index = 0;
let mut i = 1;
while i < array.len() {
if array[i] > array[max_index] {
max_index = i;
}
i += 1;
}
array[max_index]
}
//下来一段代码并不是用来运行的,而是用来描述一下函数泛型的语法格式
//关键也编译不过:binary operation `>` cannot be applied to type `T`(并不是所有的数据类型都可以比大小)
fn max<T>(array: &[T]) -> T {
let mut max_index = 0;
let mut i = 1;
while i < array.len() {
if array[i] > array[max_index] {
max_index = i;
}
i += 1;
}
array[max_index]
}
*/
//最简单的使用
fn test_1() {
struct Point<T> {
x: T,
y: T,
}
//使用时并没有声明类型,这里使用的是自动类型机制
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 1.0, y: 2.0 };
//但不允许出现类型不匹配的情况如下:
//let p3 = Point {x: 1, y: 2.0};
//x 与 1 绑定时就已经将 T 设定为 i32,所以不允许再出现 f64 的类型。
//如果我们想让 x 与 y 用不同的数据类型表示,可以使用两个泛型标识符
struct Point2<T1, T2> {
x: T1,
y: T2,
}
}
fn test_2() {
println!("-------------test_2------------");
struct Point<T1, T2> {
x: T1,
y: T2,
}
//给泛型结构体定义泛型方法
//注意,impl 关键字的后方必须有 <T>,因为它后面的 T 是以之为榜样的
impl<T1, T2> Point<T1, T2> {
fn x(&self) -> &T1 {
&self.x
}
fn y(&self) -> &T2 {
&self.y
}
}
//也可以为其中的一种泛型添加方法
impl Point<f64, i32> {
fn xx(&self) -> f64 {
self.x
}
}
let p = Point { x: 1, y: 2 };
println!("p.x = {},p.y = {}", p.x(), p.y());
let p2 = Point { x: 1.1, y: 2 };
println!("p.xx = {}", p2.xx());
//也可以随意指定泛型代表的值,只不过由于没有对应的泛型方法,所有无方法可用
let p3 = Point { x: 1.1, y: "1111111111" };
}
fn test_3() {
println!("-------------test_3------------");
/*
在使用泛型时,类型参数常常必须使用 trait 作为约束(bound)来明确规定 类型应实现哪些功能。例如下面的例子用到了 Display trait 来打印
所以它用 Display 来约束 T,也就是说 T 必须实现 Display。
*/
use std::fmt::*;
#[derive(Debug,Default)]
struct StDebug{}
//trait Debug{}
// 泛型 `T` 必须实现 `Debug` 。只要满足这点,无论什么类型
// 都可以让下面函数正常工作。
fn print_debug<T: Debug>(t: &T) {
println!("{:?}", t);
}
let tt:StDebug = Default::default();
print_debug(&tt);
}
fn main() {
test_1();
test_2();
test_3();
}