rust-泛型generics

2023-10-23 14:57:39 浏览数 (2)

泛型(generics)

rust 也有泛型,这种最早出现1970年代的Ada语言中,后来被许多基于对象和面向对象的语言所采用,包括BETA、 C 、java。 rust 也借鉴了这一特性。 这种特性让程序有更好的通用性。

1.简单示例-结构体泛型

给结构体 Point 定义一个泛型 T

代码语言:javascript复制
struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let integer = Point { x: 5, y: 10 };
    let float = Point { x: 1.0, y: 4.0 };
}

不同类型泛型

代码语言:javascript复制
struct Point<T, U> {
    x: T,
    y: U,
}

fn main() {
    let both_integer = Point { x: 5, y: 10 };
    let both_float = Point { x: 1.0, y: 4.0 };
    let integer_and_float = Point { x: 5, y: 4.0 };
}

2.函数泛型-同方法泛型

传入什么,就返回什么类型

代码语言:javascript复制
fn largest<T>(list: &[T]) -> T {

那会不会跟java一样,可以类泛型作用到方法。 rust 结构体泛型作用到 函数?

代码语言:javascript复制
fn largest<T>(list: &[T]) -> &T {
    let mut largest = &list[0];

    for item in list {
        if item > largest {
            largest = item;
        }
    }

    largest
}

fn main() {
    let number_list = vec![34, 50, 25, 100, 65];

    let result = largest(&number_list);
    println!("The largest number is {}", result);

    let char_list = vec!['y', 'm', 'a', 'q'];

    let result = largest(&char_list);
    println!("The largest char is {}", result);
}

3.方法泛型

真有这个。

用法和定义同java一样。 实现一个Point 的方法,类型为T。

代码语言:javascript复制
struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

fn main() {
    let p = Point { x: 5, y: 10 };

    println!("p.x = {}", p.x());
}

泛型指定限制(constraint) 这个例子,也是实现Point,但是类型为具体类型 f32

代码语言:javascript复制
impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
        (self.x.powi(2)   self.y.powi(2)).sqrt()
    }
}

结合 self 使用 注意 x 返回的是 self.x 所以是调用者 p1 自己的x

代码语言:javascript复制
struct Point<X1, Y1> {
    x: X1,
    y: Y1,
}

impl<X1, Y1> Point<X1, Y1> {
    fn mixup<X2, Y2>(self, other: Point<X2, Y2>) -> Point<X1, Y2> {
        Point {
            x: self.x,
            y: other.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 5, y: 10.4 };
    let p2 = Point { x: "Hello", y: 'c' };

    let p3 = p1.mixup(p2);

    println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}

结果:

代码语言:javascript复制
p3.x = 5, p3.y = c

泛型代码的性能

Rust 通过在编译时进行泛型代码的 单态化(monomorphization)来保证效率。 单态化是一个通过填充编译时使用的具体类型,将通用代码转换为特定代码的过程。

java也是一样的方式,通过泛型擦除来实现,就是 泛型信息只存在于代码编译阶段,在java的运行期(已经生成字节码文件后)与泛型相关的信息会被擦除掉。 所以其实也是在编译期做文章。

总结

rust 的很多方面,都借鉴了java的总分特性,不是指泛型,而是指后面还明更多的部分,比如迭代器,用起来很丝滑。 还有如golang部份的特性,在channel部分,用起来,就是像golang

0 人点赞