C++20 concept VS rust trait
这两个差不多,都是对一个对象约束行为,当然也有人持不同意见,如下链接 https://mcla.ug/blog/cpp20-concepts-are-not-like-rust-traits.html
上面链接的作者C++写的代码是没问题的,但是rust有问题,那个报错并不能验证他的观点。
template<typename T>
concept Stringable = requires(T a) {
{ a.stringify() }
->std::convertible_to<std::string>;
};
class Cat {
public:
// 满足Stringable约束
std::string stringify() { return "meow"; }
void pet() {
}
};
template<Stringable T>
void f(T a) {
a.pet();
}
int main() {
f(Cat());
return 0;
}
我觉得正确的rust代码是下面。
trait Stringable {
fn stringify() -> String;
}
struct Cat {
}
impl Cat {
fn pet() {}
}
struct Dog{
}
impl Dog{
fn pet(){}
}
impl Stringable for Cat {
fn stringify() -> String {
"meow".to_string()
}
}
fn f<T:Stringable>(a: T) {
}
fn main() {
let cat = Cat{};
f(cat);
let dog = Dog{};
f(dog);
}
文章的代码之所以会报错是因为她没把pet搞到trait里,rust为了安全就禁止掉了。
// 定义trait
trait Stringable {
fn stringify() -> String;
fn pet(self);
}
struct Cat {
}
impl Cat {
fn pet(self){println!("pet calledd\n");}
}
struct Dog{
}
impl Dog{
fn pet(){println!("pet calledd\n");}
}
//为Cat实现trait
impl Stringable for Cat {
fn stringify() -> String {
"meow".to_string()
}
fn pet(self){
}
}
fn f<T:Stringable>(a: T) {
a.pet();
}
fn main() {
let cat = Cat{};
f(cat);
}