gpt4 book ai didi

rust - 是否可以在rust中编写动态的 ' abstract/shared '特性

转载 作者:行者123 更新时间:2023-12-03 11:44:39 24 4
gpt4 key购买 nike

编辑:

  • link to playground with possible solution基于Locke's answer
  • link to playground with abstract trait example without generics

  • 原始问题
    MyTrait中,我尝试共享复杂的功能 doSthMyTrait是为Foo实现的。
    Foo具有内部结构 bar,其类型应为 T
    该实现应防止为每个 T重写某些其他功能。
    #[derive(Debug)]
    pub enum Status{
    Open,
    Closed,
    }

    #[derive(Debug)]
    pub struct Foo<T>{
    name: String,
    status: Status,
    bar: T

    }

    #[derive(Debug)]
    pub enum SomeError {
    Fails,
    }

    pub trait MyTrait<T> {
    type Output;

    fn setStatus(&self, status: Status) -> Status;
    fn getStatus(&self) -> Status;

    fn doSth(&self) -> Result<Self::Output, SomeError>
    {
    if super::variant_eq(&self.getStatus(), &Status::Closed) {
    self.setStatus(Status::Open);
    return Ok(T);
    };
    return Err(SomeError::Fails);
    }

    }

    impl<T> MyTrait<T> for Foo<T> {
    type Output = Foo<T>;

    fn setStatus(&self, status: Status) -> Status{
    self.status = status;
    }

    fn getStatus(&self) -> Status{
    self.status;
    }

    }
    doSth无法编译(其他人也可能不会,它还没走得那么远)
  • 预期的返回Result<Self::Output, SomeError>和实际的返回return Ok(T)时,编译器会说T is not a value
  • 预期的返回Result<Self::Output, SomeError>和实际的返回return Ok(Self::Output)时,编译器会说associated item not found in `Self`
  • 预期的返回Result<T, SomeError>和实际的返回return Ok(())时,编译器会说expected type parameter T, found ()

  • 我确实找到了泛型的示例,共享函数的示例,但是没有找到该方法,因此我不确定该方法是否合理。
    如果有理由朝这个方向努力,那么前进的方向是什么?

    最佳答案

    对于初学者,Status应该派生PartialEq,以便您可以检查相等性。为variant_eq实现自己的enum函数几乎总是错误的方法。
    我也建议您导出Copy以便于使用。

    #[derive(Debug, PartialEq, Eq, Copy, Clone)]
    pub enum Status {
    Open,
    Closed,
    }
    有了这些,这里有一些关于如何使您的代码正确运行的快速评论
    pub trait MyTrait<T> {
    type Output;

    // This set should probably take a mutable reference
    fn set_status(&mut self, status: Status);
    fn get_status(&self) -> Status;

    // You need some way to get output
    fn get_output(&mut self) -> Self::Output;

    // Now it has everything it needs to work correctly.
    fn doSth(&mut self) -> Result<Self::Output, SomeError> {
    // Thanks to PartialEq we can use == as normal
    if self.getStatus() == Status::Closed {
    self.set_status(Status::Open);

    // Call function that will be implemented later to provide output
    return Ok(self.get_output())
    }

    // Return is assumed for last line in function
    Err(SomeError::Fails)
    }
    }
    即使您不能派生 PartialEq,也可以至少使用一个匹配项。
    match self.getStatus() {
    Status::Closed => {
    self.set_status(Status::Open);
    Ok(self.get_output())
    }
    _ => Err(SomeError::Fails),
    }
    有了所有这些,您就可以像执行原始操作一样实现foo了。
    impl<T> MyTrait<T> for Foo<T> {
    type Output = Foo<T>;

    // Required mutable reference to work
    fn set_status(&mut self, status: Status) {
    self.status = status;
    }

    fn get_status(&self) -> Status {
    // ; would have prevented value from being returned
    // Status also needs to implement Copy for this to work
    self.status
    }

    fn get_output(&mut self) -> Self::Output {
    // Since you have it return an owned value, you need to either clone
    // self, or make get_output consume self
    self.clone()
    }
    }

    关于rust - 是否可以在rust中编写动态的 ' abstract/shared '特性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64250692/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com