如何静态地将 `chrono::format::strftime` 转换为 `chrono::format::Item`?
How to transform `chrono::format::strftime` to `chrono::format::Item` statically?
我有一个我的应用程序支持的 chrono::format::strftime
格式的静态数组。
我想避免在 运行 时间内解析它们,所以我定义了一个 lazy_static!
块,将它们解析为 chrono::format::Item
.
的集合
但是,当我尝试遍历已解析的集合时,出现错误:
the trait bound `&chrono::format::StrftimeItems<'_>: std::iter::Iterator` is not satisfied
这是一个简短的复制:
#[macro_use]
extern crate lazy_static;
extern crate chrono;
use chrono::DateTime;
use chrono::offset::FixedOffset;
use chrono::format::{Parsed, parse};
use chrono::format::strftime::StrftimeItems;
static FORMATS : &[&'static str] = &["%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S%.f"];
lazy_static! {
static ref PARSED_FORMATS : Vec<StrftimeItems<'static>> = FORMATS
.iter()
.map(|format| StrftimeItems::new(format))
.collect();
}
fn parse_datetime(s: &str) -> Option<DateTime<FixedOffset>> {
for format in PARSED_FORMATS.iter() {
let mut parsed = Parsed::new();
let dt = parse(&mut parsed, &s, format)
.and_then(|_| parsed.to_datetime() );
if dt.is_ok() {
return dt.ok()
}
}
return None
}
尝试在循环中取消引用 format
会出现此错误:
error[E0507]: cannot move out of borrowed content
--> src\main.rs:21:35
|
21 | let dt = parse(&mut parsed, &s, *format)
| ^^^^^^^ cannot move out of borrowed content
error: aborting due to previous error
尝试克隆 format
似乎可行,但克隆在这里似乎是多余的,我想避免它。
这是正确的方法吗?或者使用宏可能是更好的选择?
StrftimeItems
是一个迭代器,而不是一个可迭代的容器(就像 Vec
是)。当你推进一个迭代器时,你不能倒带它。 parse
必须按值接收一个迭代器,这意味着您必须获取一个 StrftimeItems
我们的向量(这意味着您不能在之后重用它)或克隆 StrftimeItems
存储在向量。通过克隆 StrftimeItems
,您可以生成一个新的迭代器,其状态与原始状态不同(即推进一个不会推进另一个)。
I'd like to avoid parsing them during run time
但是,StrftimeItems
不会让你达到目的,因为StrftimeItems
lazily parses the format string as the iterator advances。
相反,我建议您将该迭代器的结果收集到 Vec<Item<'static>>
。
#[macro_use]
extern crate lazy_static;
extern crate chrono;
use chrono::DateTime;
use chrono::offset::FixedOffset;
use chrono::format::{Item, Parsed, parse};
use chrono::format::strftime::StrftimeItems;
static FORMATS : &[&'static str] = &["%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S%.f"];
lazy_static! {
static ref PARSED_FORMATS : Vec<Vec<Item<'static>>> = FORMATS
.iter()
.map(|format| StrftimeItems::new(format).collect())
.collect();
}
fn parse_datetime(s: &str) -> Option<DateTime<FixedOffset>> {
for format in PARSED_FORMATS.iter() {
let mut parsed = Parsed::new();
let dt = parse(&mut parsed, &s, format.iter().cloned())
.and_then(|_| parsed.to_datetime() );
if dt.is_ok() {
return dt.ok()
}
}
return None
}
现在,当我们调用 parse
时,我们传递 format.iter().cloned()
。 format
是一个 Vec<Item<'static>>
,iter()
在对 Item
的引用上生成一个新的迭代器,并且 cloned()
调整迭代器以便每个 Item
按值返回(通过克隆它们实现)而不是按引用返回(因为 parse
期望迭代器超过 Item
值,而不是 Item
引用)。
我有一个我的应用程序支持的 chrono::format::strftime
格式的静态数组。
我想避免在 运行 时间内解析它们,所以我定义了一个 lazy_static!
块,将它们解析为 chrono::format::Item
.
但是,当我尝试遍历已解析的集合时,出现错误:
the trait bound `&chrono::format::StrftimeItems<'_>: std::iter::Iterator` is not satisfied
这是一个简短的复制:
#[macro_use]
extern crate lazy_static;
extern crate chrono;
use chrono::DateTime;
use chrono::offset::FixedOffset;
use chrono::format::{Parsed, parse};
use chrono::format::strftime::StrftimeItems;
static FORMATS : &[&'static str] = &["%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S%.f"];
lazy_static! {
static ref PARSED_FORMATS : Vec<StrftimeItems<'static>> = FORMATS
.iter()
.map(|format| StrftimeItems::new(format))
.collect();
}
fn parse_datetime(s: &str) -> Option<DateTime<FixedOffset>> {
for format in PARSED_FORMATS.iter() {
let mut parsed = Parsed::new();
let dt = parse(&mut parsed, &s, format)
.and_then(|_| parsed.to_datetime() );
if dt.is_ok() {
return dt.ok()
}
}
return None
}
尝试在循环中取消引用 format
会出现此错误:
error[E0507]: cannot move out of borrowed content
--> src\main.rs:21:35
|
21 | let dt = parse(&mut parsed, &s, *format)
| ^^^^^^^ cannot move out of borrowed content
error: aborting due to previous error
尝试克隆 format
似乎可行,但克隆在这里似乎是多余的,我想避免它。
这是正确的方法吗?或者使用宏可能是更好的选择?
StrftimeItems
是一个迭代器,而不是一个可迭代的容器(就像 Vec
是)。当你推进一个迭代器时,你不能倒带它。 parse
必须按值接收一个迭代器,这意味着您必须获取一个 StrftimeItems
我们的向量(这意味着您不能在之后重用它)或克隆 StrftimeItems
存储在向量。通过克隆 StrftimeItems
,您可以生成一个新的迭代器,其状态与原始状态不同(即推进一个不会推进另一个)。
I'd like to avoid parsing them during run time
但是,StrftimeItems
不会让你达到目的,因为StrftimeItems
lazily parses the format string as the iterator advances。
相反,我建议您将该迭代器的结果收集到 Vec<Item<'static>>
。
#[macro_use]
extern crate lazy_static;
extern crate chrono;
use chrono::DateTime;
use chrono::offset::FixedOffset;
use chrono::format::{Item, Parsed, parse};
use chrono::format::strftime::StrftimeItems;
static FORMATS : &[&'static str] = &["%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S%.f"];
lazy_static! {
static ref PARSED_FORMATS : Vec<Vec<Item<'static>>> = FORMATS
.iter()
.map(|format| StrftimeItems::new(format).collect())
.collect();
}
fn parse_datetime(s: &str) -> Option<DateTime<FixedOffset>> {
for format in PARSED_FORMATS.iter() {
let mut parsed = Parsed::new();
let dt = parse(&mut parsed, &s, format.iter().cloned())
.and_then(|_| parsed.to_datetime() );
if dt.is_ok() {
return dt.ok()
}
}
return None
}
现在,当我们调用 parse
时,我们传递 format.iter().cloned()
。 format
是一个 Vec<Item<'static>>
,iter()
在对 Item
的引用上生成一个新的迭代器,并且 cloned()
调整迭代器以便每个 Item
按值返回(通过克隆它们实现)而不是按引用返回(因为 parse
期望迭代器超过 Item
值,而不是 Item
引用)。