嗨,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
超特征。:-(