Rust 在线摸索(十二):泛型之where、反面代码初探
终于到了 where从句。
看介绍似乎是 bound 的一种等价语法,这句貌似是额外功能,“arbitrary types”何意待查:
Additionally, where clauses can apply bounds to arbitrary types, rather than just to type parameters.
中文化时,从这个报警看方法名的确建议下划线风格。
warning: trait method `输出Option` should have a snake case name
--> src/main.rs:4:8
|
4 | fn 输出Option(self);
| ^^^^^^^^^^ help: convert the identifier to snake case: `输出_option`
|
= note: `#[warn(non_snake_case)]` on by default
修正后的中文化代码:
use std::fmt::Debug;
trait 输出Option类 {
fn 输出_option(self);
}
// Because we would otherwise have to express this as `T: Debug` or
// use another method of indirect approach, this requires a `where` clause:
impl<T> 输出Option类 for T where
Option<T>: Debug {
// We want `Option<T>: Debug` as our bound because that is what's
// being printed. Doing otherwise would be using the wrong bound.
fn 输出_option(self) {
println!("{:?}", Some(self));
}
}
fn main() {
let 矢量 = vec![1, 2, 3];
矢量.输出_option();
}
输出:Some([1, 2, 3])
根据注释,把 Option<T>: Debug
改成了 T: Debug
,想看看有何不同。
结果输出相同,没有其他反馈。
然后去掉where用参数bound代替:impl<T: Debug> 输出Option类 for T
,运行输出仍相同。
whatever。。。
反面代码
回看这段(源自 此答):
对于贴代码截图却不附上出处链接的,个人有本能警惕。用谷歌搜 "servicefactory<Request<pin<box<dyn"
终于找到 出处。
文字格式如下:
impl<T, S, B, X, U> ServiceFactory<(T, Option<SocketAddr>)> for H1Service<T, S, B, X, U> where
T: 'static + AsyncRead + AsyncWrite + Unpin,
S: ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Config = ()>,
B: MessageBody,
X: ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Config = (), Response = Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>,
U: ServiceFactory<(Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Framed<T, Codec>), Config = (), Response = ()>,
<S as ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>>::Future: 'static,
<S as ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>>::Error: Into<Response<BoxBody>>,
<S as ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>>::Response: Into<Response<B>>,
<S as ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>>::InitError: Debug,
<X as ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>>::Future: 'static,
<X as ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>>::Error: Into<Response<BoxBody>>,
<X as ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>>>::InitError: Debug,
<U as ServiceFactory<(Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Framed<T, Codec>)>>::Future: 'static,
<U as ServiceFactory<(Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Framed<T, Codec>)>>::Error: Display,
<U as ServiceFactory<(Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Framed<T, Codec>)>>::Error: Into<Response<BoxBody>>,
<U as ServiceFactory<(Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Framed<T, Codec>)>>::InitError: Debug,
[src 链接](https://cseweb.ucsd.edu/classes/sp22/cse223B-a/tribbler/src/actix_http/h1/service.rs.html#269-333)的这段内容与 github 此段代码 相同:
impl<T, S, B, X, U> ServiceFactory<(T, Option<net::SocketAddr>)> for H1Service<T, S, B, X, U>
where
T: AsyncRead + AsyncWrite + Unpin + 'static,
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Response<BoxBody>>,
S::Response: Into<Response<B>>,
S::InitError: fmt::Debug,
B: MessageBody,
X: ServiceFactory<Request, Config = (), Response = Request>,
X::Future: 'static,
X::Error: Into<Response<BoxBody>>,
X::InitError: fmt::Debug,
U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>,
U::Future: 'static,
U::Error: fmt::Display + Into<Response<BoxBody>>,
U::InitError: fmt::Debug,
相较而言,下面这段的可读性好很多。尤其是 S 和 U 的类型展开之后,满屏重复代码的视觉效果很冲击。
以where从句第二项作对比:
S: ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>, Config = ()>,
<=>
S: ServiceFactory<Request, Config = ()>,
先找 Request 后面多出来的这段 <Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>
,在 Request 里,找到个 trait implementation:
impl ServiceFactory<Request<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>> + 'static, Global>>>> for ExpectHandler
猜测,是文档将类型描述展开了。现在介意的是,这样展开后是否符合Rust语法。