我是 Rust 的新手,对泛型类型的使用有点困惑。
考虑以下场景:
我可以像这样创建一个 Date 类型:
use chrono::prelude::*;
fn main() {
let date = Utc.ymd(2021, 1, 1);
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我创建一个函数foo
来做类似的事情:
use chrono::prelude::*;
fn foo<Tz: TimeZone>(date: Date<Tz>) {
let other_date = Tz.ymd(2020, 1, 1);
}
fn main() {
let date = Utc.ymd(2021, 1, 1);
foo(date);
}
Run Code Online (Sandbox Code Playgroud)
我希望Tz
被替换为Utc
,并Tz.ymd
等效于Utc.ymd
,但事实并非如此:
error[E0423]: expected value, found type parameter `Tz`
--> src/main.rs:4:20
|
4 | let other_date = Tz.ymd(2020, 1, 1);
| ^^ not a value
Run Code Online (Sandbox Code Playgroud)
这让我认为它需要先实例化?但是为什么一开始就不需要呢?我在这里误解了什么?
chrono::offset::Utc
是一个类似单元的 struct。这意味着它既是具有单个值的类型的名称,又是值本身的名称,例如()
既是类型又是值。这是一个方便的功能,但有时会令人困惑。
在Utc.ymd(2021, 1, 1)
您使用Utc
作为值。只有值可以使用.
syntax.¹然而,在foo
,Tz
是一个类型参数。它可以是实现 的任何类型TimeZone
,因此您不能凭空创建type的值Tz
。不过,你可以做的是采取timezone
的Date<Tz>
这是在通过了:
fn foo<Tz: TimeZone>(date: Date<Tz>) {
let other_date = date.timezone().ymd(2020, 1, 1);
}
Run Code Online (Sandbox Code Playgroud)
这会克隆Tz
属于 的date
并使用克隆创建other_date
.
¹ 的完全限定版本Utc.ymd(2021, 1, 1)
是<Utc as TimeZone>::ymd(&Utc, 2021, 1, 1)
第一个Utc
是类型 Utc
,第二个是值 Utc
。
归档时间: |
|
查看次数: |
53 次 |
最近记录: |