如何让Rust函数my_func同时接受Tz和FixedOffset两种类型参数?
问题描述
我有以下Rust代码:
src/main.rs
use chrono_tz::Tz; use chrono::FixedOffset; use chrono::{NaiveDateTime, TimeZone, NaiveDate}; fn my_func(from_tz: Tz, ndt: NaiveDateTime){ let res = from_tz.from_local_datetime(&ndt); println!("res: {:?}", res); } fn main() { let area_location: Tz = "UTC".parse().unwrap(); let hour = 3600; let fixed_offset: FixedOffset = FixedOffset::east_opt(5 * hour).unwrap(); let ndt = NaiveDate::from_ymd_opt(2038, 1, 19).unwrap().and_hms_opt(3, 14, 08).unwrap(); my_func(area_location, ndt) }
Cargo.toml
[package] name = "tmp" version = "0.1.0" edition = "2021" [dependencies] chrono = "0.4.23" chrono-tz = "0.8.1" regex = "1.7.1"
这段代码能正常运行,输出:
res: Single(2038-01-19T03:14:08UTC)
如果把main函数最后一行改成my_func(fixed_offset, ndt),同时将my_func的from_tz参数类型改为FixedOffset,代码也能正常运行,输出:
res: Single(2038-01-19T03:14:08+05:00)
现在应用无法确定会收到Tz还是FixedOffset类型的参数,但无论哪种情况,都希望传入my_func并执行from_tz.from_local_datetime(&ndt)操作。需要让my_func同时接受这两种类型的参数。
解决方案
利用Rust的泛型+Trait约束即可实现,因为Tz和FixedOffset都实现了chrono::TimeZone trait,而from_local_datetime正是该trait提供的方法。
修改后的my_func代码如下:
fn my_func<T: TimeZone>(from_tz: T, ndt: NaiveDateTime) { let res = from_tz.from_local_datetime(&ndt); println!("res: {:?}", res); }
修改后无需额外改动,my_func就能同时接受Tz和FixedOffset类型的参数。测试用的main函数示例:
fn main() { let area_location: Tz = "UTC".parse().unwrap(); let hour = 3600; let fixed_offset: FixedOffset = FixedOffset::east_opt(5 * hour).unwrap(); let ndt = NaiveDate::from_ymd_opt(2038, 1, 19).unwrap().and_hms_opt(3, 14, 08).unwrap(); // 传入Tz类型 my_func(area_location, ndt); // 传入FixedOffset类型 my_func(fixed_offset, ndt); }
运行后输出:
res: Single(2038-01-19T03:14:08UTC) res: Single(2038-01-19T03:14:08+05:00)
核心逻辑:通过泛型参数T并约束它必须实现TimeZone trait,只要传入的类型满足该约束,就能调用trait中定义的from_local_datetime方法,完美适配两种时区类型。
内容的提问来源于stack exchange,提问作者ignoring_gravity
相关产品推荐
相关产品推荐

