1

嗨,Stack Overflow 的 Rustaceans,我正在继续我在 Rust 中的新项目,但我仍然遇到了我一直在尝试构建的全天候特性。作为参考,我选择了第二种解决方案(向我推荐的那个)。

我现在面临的挑战是,我发现指定通用时区的需要正在“渗透”到其他结构中。本质上,如果任何结构需要包含时钟(或任何其他包含时钟的结构),则结构也需要泛型,即使这些结构与时间或时区关系不大。

// Assert for purposes of argument that this struct is not really about time
// or time zones and it is confusing why one is required.
pub struct <Tz: TimeZone> UnrelatedThing {
  // Other stuff...

  clock: &dyn Clock<Tz>,
}

我最终想要达到一个点,我可以将时区存储为某物的属性,并能够拥有一个返回DateTime该时区对象的方法:

struct TimeRelatedThing {
  tz: dyn TimeZone,
}

impl TimeRelatedThing {
  pub fn now(&self) -> DateTime<??> {
    Utc::now().with_timezone(&self.tz)
  }
}

我无法正常工作的部分是DateTime<??>部分,因为在编译时不一定知道时区。解决这个问题的正确方法是什么?看起来我可以做到Box<dyn impl Datelike + Timelike>,但在我天真的理解看来,这似乎是高开销?对于想要针对我的函数编写代码的人来说,这似乎是很多工作。

我应该提到我是 Rust 的新手,我完全有可能误解了一些基本的东西,但是我查看了文档以试图更好地理解并且没有找到我想要的东西。

更新

经过更多的迭代,我有一个状态,我总是要求时区作为参数:

use chrono::{DateTime, TimeZone, Utc};

/// A trait representing the internal clock for timekeeping requirements.
/// Note that for some testing environments, clocks may be stubs.
pub trait Clock {
  /// Return the current datetime.
  fn now<Tz: TimeZone>(&self, tz: Tz) -> DateTime<Tz>;
}

/// A clock that reliably reports system time in the requested time zone.
pub struct SystemClock {}
impl SystemClock {
  /// Return a new system clock in the given time zone.
  pub fn new() -> SystemClock {
    SystemClock {}
  }
}
impl Clock for SystemClock {
  /// Return the current datetime.
  fn now<Tz: TimeZone>(&self, tz: Tz) -> DateTime<Tz> {
    Utc::now().with_timezone(&tz)
  }
}

/// A stub clock that reports "stub time", useful for replaying historical
/// data and other purposes.
pub struct StubClock {
  /// The current "now" time, in UTC.
  cursor: DateTime<Utc>,
}
impl StubClock {
  /// Return a new stub clock in the given time zone, and with the given
  /// starting time.
  pub fn new<Tz: TimeZone>(start: DateTime<Tz>) -> StubClock {
    StubClock { cursor: start.with_timezone(&Utc) }
  }

  /// Set the cursor to the current time.
  pub fn set_cursor<Tz: TimeZone>(&mut self, cursor: DateTime<Tz>) -> &Self {
    self.cursor = cursor.with_timezone(&Utc);
    return self;
  }
}
impl Clock for StubClock {
  /// Return the current datetime.
  fn now<Tz: TimeZone>(&self, tz: Tz) -> DateTime<Tz> {
    self.cursor.clone().with_timezone(&tz)
  }
}

这似乎仍然不如将时区作为我的时钟的属性,因为我希望时钟始终在单个时区运行,尽管有无可争辩的优势。

但是,这会产生一个新问题,即 nowClock不是“对象安全”特征,因为TimeZone它似乎具有Sized超特征。:-(

4

0 回答 0