Traits(特质)

// 特质
pub trait Summary {
fn summarize(&self) -> String;
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
// 实现特质
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{}, by {} ({})", self.headline, self.author, self.location)
}
}
pub struct Tweet {
pub username: String,
pub content: String,
pub reply: bool,
pub retweet: bool,
}
// 实现特质
impl Summary for Tweet {
fn summarize(&self) -> String {
format!("{}: {}", self.username, self.content)
}
}
// 使用特质
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
};
println!("1 new tweet: {}", tweet.summarize());
// 缺省实现
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
// 使用特质的缺省实现
let article = NewsArticle {
headline: String::from("Penguins win the Stanley Cup Championship!"),
location: String::from("Pittsburgh, PA, USA"),
author: String::from("Iceburgh"),
content: String::from("The Pittsburgh Penguins once again are the best
hockey team in the NHL."),
};
println!("New article available! {}", article.summarize());
// 有缺省实现的方法可以调用没有缺省实现的方法
pub trait Summary {
fn summarize_author(&self) -> String;
fn summarize(&self) -> String {
format!("(Read more from {}...)", self.summarize_author())
}
}
impl Summary for Tweet {
fn summarize_author(&self) -> String {
format!("@{}", self.username)
}
}
let tweet = Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
};
println!("1 new tweet: {}", tweet.summarize());
// 作为参数类型的特质
pub fn notify(item: impl Summary) {
println!("Breaking news! {}", item.summarize());
}
pub fn notify<T: Summary>(item: T) {
println!("Breaking news! {}", item.summarize());
}
// 两个特质类型的参数
pub fn notify(item1: impl Summary, item2: impl Summary) {
pub fn notify<T: Summary>(item1: T, item2: T) {
// 多个特质
fn some_function<T: Display + Clone, U: Clone + Debug>(t: T, u: U) -> i32
// where 子句
fn some_function<T, U>(t: T, u: U) -> i32
where T: Display + Clone,
U: Clone + Debug
{
// 返回特质
fn returns_summarizable() -> impl Summary {
Tweet {
username: String::from("horse_ebooks"),
content: String::from("of course, as you probably already know, people"),
reply: false,
retweet: false,
}
}
// 根据特质选择性地实现方法
use std::fmt::Display;
struct Pair<T> {
x: T,
y: T,
}
impl<T> Pair<T> {
fn new(x: T, y: T) -> Self {
Self {
x,
y,
}
}
}
impl<T: Display + PartialOrd> Pair<T> {
fn cmp_display(&self) {
if self.x >= self.y {
println!("The largest member is x = {}", self.x);
} else {
println!("The largest member is y = {}", self.y);
}
}
}

泛型

// 泛型函数
fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
let mut largest = list[0];
for &item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
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);
// 泛型结构体
struct Point<T> {
x: T,
y: T,
}
let integer = Point { x: 5, y: 10 };
let float = Point { x: 1.0, y: 4.0 };
// 带两个类型参数的泛型结构体
struct Point<T, U> {
x: T,
y: U,
}
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 };
// 标准库中的泛型枚举
enum Option<T> {
Some(T),
None,
}
enum Result<T, E> {
Ok(T),
Err(E),
}
// 泛型方法
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
let p = Point { x: 5, y: 10 };
println!("p.x = {}", p.x());
// 针对具体类型实现泛型结构体的方法(==C++的全特化)
impl Point<f32> {
fn distance_from_origin(&self) -> f32 {
(self.x.powi(2) + self.y.powi(2)).sqrt()
}
}
// 带类型参数的泛型方法
struct Point<T, U> {
x: T,
y: U,
}
impl<T, U> Point<T, U> {
fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
Point {
x: self.x,
y: other.y,
}
}
}
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);

生命周期(Lifetimes)

// 带生命周期的引用类型
&i32 // a reference
&'a i32 // a reference with an explicit lifetime
&'a mut i32 // a mutable reference with an explicit lifetime
// 带生命周期注解的函数
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
// 调用带生命周期注解的函数
let string1 = String::from("long string is long");
{
let string2 = String::from("xyz");
let result = longest(string1.as_str(), string2.as_str());
println!("The longest string is {}", result);
}
// 调用带生命周期注解的函数
let string1 = String::from("long string is long");
let result;
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str()); // error
}
println!("The longest string is {}", result);
// 带生命周期注解的结构体
struct ImportantExcerpt<'a> {
part: &'a str,
}
let novel = String::from("Call me Ishmael. Some years ago...");
let first_sentence = novel.split('.')
.next()
.expect("Could not find a '.'");
let i = ImportantExcerpt { part: first_sentence };
// 带生命周期注解的方法
impl<'a> ImportantExcerpt<'a> {
fn level(&self) -> i32 {
3
}
}
// 静态生命周期
let s: &'static str = "I have a static lifetime.";

闭包(Closures)

// 闭包
fn add_one_v1 (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x| { x + 1 };
let add_one_v4 = |x| x + 1 ;
let add_one_v5: fn(u32) -> u32 = |x| x + 1;
// 没有泛型闭包
let example_closure = |x| x;
let s = example_closure(String::from("hello"));
let n = example_closure(5); // error
// 闭包可以捕获外层变量,局部函数不行
let x = 4;
let equal_to_x = |z| z == x;
assert!(equal_to_x(4));
fn equal_to_x(z: i32) -> bool { z == x } // error
// Move 捕获
let x = vec![1, 2, 3];
let equal_to_x = move |z| z == x;
println!("can't use x here: {:?}", x); // error

Iterator 特质

trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
// methods with default implementations elided
}
// 使用 Iterator 特质
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter {
println!("Got: {}", val);
}
// 使用 Iterator 特质
let mut v1_iter = v1.iter();
assert_eq!(v1_iter.next(), Some(&1));
assert_eq!(v1_iter.next(), Some(&2));
assert_eq!(v1_iter.next(), Some(&3));
assert_eq!(v1_iter.next(), None);
// sum 方法
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
assert_eq!(total, 6);
// map, collect, filter 方法
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
assert_eq!(v2, vec![2, 3, 4]);
// 实现 Iterator 特质
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
self.count += 1; if self.count < 6 {
Some(self.count)
} else {
None
}
}
}
// 使用 Iterator 特质
let mut counter = Counter::new();
assert_eq!(counter.next(), Some(1));
assert_eq!(counter.next(), Some(2));
assert_eq!(counter.next(), Some(3));
assert_eq!(counter.next(), Some(4));
assert_eq!(counter.next(), Some(5));
assert_eq!(counter.next(), None);
let sum: u32 = Counter::new().zip(Counter::new().skip(1))
.map(|(a, b)| a * b)
.filter(|x| x % 3 == 0)
.sum();
assert_eq!(18, sum);

Rust语言学习笔记(6)的更多相关文章

  1. Rust语言学习笔记(7)

    模块 // 兄弟模块 mod network { fn connect() { } } mod client { fn connect() { } } // 父子模块 mod network { fn ...

  2. Rust语言学习笔记(5)

    Structs(结构体) struct User { username: String, email: String, sign_in_count: u64, active: bool, } let ...

  3. Rust语言学习笔记(4)

    Variables and Mutability(变量和可变性) 变量声明有三种:不变量(运行期的常量),变量以及(编译期的)常量. 变量可以重复绑定,后声明的变量覆盖前面声明的同名变量,重复绑定时可 ...

  4. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  5. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  6. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

  7. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  8. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  9. Go语言学习笔记十三: Map集合

    Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...

随机推荐

  1. win10 php7.2 nginx 安装 imagick,适用于phpstudy

    imagick 拓展的下载地址 https://windows.php.net/downloads/pecl/releases/imagick/ 可惜的是这个地址最新版没有php7.2, 如果是7.1 ...

  2. java中原生的发送http请求(无任何的jar包导入)

    package com.teamsun.pay.wxpay.util; import java.io.BufferedReader; import java.io.IOException; impor ...

  3. Keras 实现一个简单GAN

    Keras 实现一个简单GAN 代码中需提供: Loss Function  参见Keras 或者 Tensorflow 文档 model_param_matrix   反向调整的模型参数/参数矩阵 ...

  4. python实现排序算法(一)——插入排序算法

    ''' 插入排序算法 原始数据data 排序数据后数据SortedData,默认是从小打大排序 1.从data第一个元素开始,该元素赋值给SortedData[0],可以认为SortedData已经被 ...

  5. HBase核心知识和应用案例

    Hbase 热点问题? Hbase 预分区 Hbase Rowkey 设计原则 Hbase 常见避免热点问题方法 Hbase 总结 Hbase 连续查询的Rowkey设计 Hbase 随机查询的Row ...

  6. virt-install vs qemu-kvm创建guest主机

    virt-install是rpm包python-virtinst里的一个工具 -- 其实就是一个python写的脚本 .基本可以理解为virsh-install是qemu-kvm工具的人性化实现.可以 ...

  7. Android最新版支付宝支付集成

    上次集成支付宝支付已经很久了,今天写东西用到了支付宝支付,就大致写一下流程: 去蚂蚁金服下载最新版的Android&IOS端SDK 全部文档 -- 资源下载 -- App支付客户端 下载后解压 ...

  8. MyBatis Generator 生成数据库自带中文注释

    1. maven依赖 <!-- mybatis生成 jar包 --> <dependency> <groupId>org.mybatis.generator< ...

  9. Ubuntu安装MyEclise16 过程差不多

    选择好安装路径,和workpace路径,可能会因为工作空间放的位置不太对,导致myeclipse出现问题. 1.Ubuntu安装MyEclise10 不知道为什么网上会有那么多安装过程,还有配置目录和 ...

  10. asp 月末 月初

    上个月第一天:<%=dateadd("m",-1,year(date)&"-"&month(date)&"-1" ...