上个星期,Rust社区在异步IO,Future和Tokio重构,Async/Await机制设计上有了重大进展。详情参见Team成员Without Boats的博文async/await一个更好的建议,以及Hyper服务器作者seanmonstar在poll方法增加明确的task::Context参数RFC中的关于WithContext的精巧构思等,以至于核心Team成员Auron Turon惊叹:不可思议的rust一周。这里面都涉及一个原来Rust社区不怎么重视的问题:arbitray self type(任意自类型),使用这个类型,上面两个问题可以很好的解决,但是现在这个类型在rust中只是处于试验阶段,并且只是部分支持,还有些问题有待解决。现在的rust核心团队已经意识到这个问题,把它作为当前的优先问题,估计要不了多久,就会出现关于任意自类型的RFC,让我们拭目以待。
那么这个类型到底是个神马鬼呢,我们还是举个简单的例子看看:
pub struct Person {
name: String,
age: u8,
}
//对上面的结构,增加方法
impl Person {
pub fn intro(&self) {
println!("My name is {}, {} years old",self.name,self.age);
}
pub fn rename(&mut self,name: String) {
self.name=name;
}
pub fn old(self,years: u8) ->Person {
Person { name: self.name,age: self.age+years}
}
}
上面三个方法里面的第一个参数就是rust目前支持的自类型参数 分别为self,&self,&mut self,对应的类型分别是Self,&Self,&mut Self 这个大家很熟悉了,假设我们再加上另外一个方法
impl Person {
pub fn test(self: Rc<Self>) {}
} //Rc<Self>可以deref到Self
调用的时候这样:Rc::new(person).test(); 上面是我假想的构造,目前实验的似乎只支持trait方法。 更进一步,这个类型说明中self:SomeType,SomeType可以为任意类型,只要SomeType 可以deref到Self类型就行,所以叫任意自类型。这个构想很奇妙吧?! 参见任意自类型问题跟踪。
神马是deref? 参见Rust book的Deref 转换。
use std::ops::Deref;
pub struct PowerPerson {
man: Person,
power: u8,
}
impl Deref for PowerPerson {
type Target=Person;
fn deref(&self)->Person {
&self.man
}
}
这样我可以给Person添加方法
impl Person {
pub fn test1(self: PowerPerson) ->Something {}
} //在这个方法中实际上隐含了PowerPerson的power参数...
这样设计的好处是可以对Self类型更多扩展或者限制,比喻Async/Await设计中的Anchor<&mut Self> 就增加了限制,seanmonstar建议的withContext类型,就在Self类型中携带了Context参数。
但是这个任意自类型也是很危险的设计,搞不好会冲突rust的核心理念:内存安全,所以如何设计,如何调用都要考虑周详。
目前rust正处于蓬勃发展期,各种奇思妙想应运而生,像制约类型系统的HKT类型等,还需要trait系统的重构,但是目前引导rust发展的语言专家有足够的信心解决这些问题,rust的前途还是很光明的。
有Haskell的爱好者说,这是haskell的monad中的一种,在Haskell中实现这个很简单...,偶实在是搞不懂了 :).
评论区
写评论不出所料,任意自类型的RFC已经出台。名字改为定制自类型.
学习 Mark
干货,学习了