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);

    }

https://www.codingame.com/playgrounds/54888/rust-for-python-developers---operators/method-and-associated-functions