以下面一个 test 示例说明 tuple struct 的类型标识在不同的位置分别具有 type 与 fn pointer 双重身份:
#[test]
fn tuple_struct() {
// Tuple 标识符具有双重身份,在类型位置时为 tuple struct,在函数位置时为函数指针 fn(i64, &'static str) -> Tuple {Tuple}
struct Tuple(i64, &'static str);
let t: Tuple =// 作为类型
Tuple(0i64, "hi"); // 作为函数指针
fn foo<T1, T2, U, F: FnOnce(T1, T2) -> U>(op: F) {}
foo(Tuple); // 作为函数指针,且实现了 FnOnce(T1, T2) -> U,可以编译通过
fn foo2<T1, T2, F: FnOnce(T1, T2)>(op: F) {}
foo2(Tuple); // 作为函数指针,但未实现 FnOnce(T1, T2),无法编译通过,根据编译器提示可以验证 Tuple 的函数指针身份:
// error[E0271]: type mismatch resolving `<fn(i64, &'static str) -> Tuple {Tuple} as FnOnce<(i64, &'static str)>>::Output == ()`
// --> src/lib.rs:92:5
// |
// | fn foo2<T1, T2, F: FnOnce(T1, T2)>(op: F) {}
// | -------------- required by this bound in `foo2`
// | foo2(Tuple); // 作为函数指针,但未实现 FnOnce(T1, T2),无法编译通过,根据编译器提示可以验证 Tuple 的函数指针身份 ...
// | ^^^^ expected `()`, found struct `Tuple`
foo(t); // t 只是 Tuple 类型的实例,不能像 Tuple 一样作为函数指针,无法编译通过:
// error[E0277]: expected a `FnOnce<(_, _)>` closure, found `Tuple`
// --> src/lib.rs:89:9
// |
// | fn foo<T1, T2, U, F: FnOnce(T1, T2) -> U>(op: F) {}
// | ------------------- required by this bound in `foo`
// ...
// | foo(t); // t 只是 Tuple 类型的实例,不能像 Tuple 一样作为函数指针,无法编译通过
// | ^ expected an `FnOnce<(_, _)>` closure, found `Tuple`
// |
// = help: the trait `FnOnce<(_, _)>` is not implemented for `Tuple`
}
在 enum 中 tuple struct 枚举项同样具有 fn pointer 身份:
#[test]
fn enum_tuple_struct() {
enum Enum {
Tuple(i8, u8) // 具有第二身份 fn(i8, u8) -> tuple_struct::Enum {tuple_struct::Enum::Tuple}
}
let _: Enum = Enum::Tuple(0, 0); // 作为函数指针
fn foo<T1, T2, U, F: FnOnce(T1, T2) -> U>(op: F) {}
foo(Enum::Tuple); // 作为函数指针,且实现了 FnOnce(T1, T2) -> U,可以编译通过
fn foo2<T1, T2, F: FnOnce(T1, T2)>(op: F) {}
foo2(Enum::Tuple); // 作为函数指针,但未实现 FnOnce(T1, T2),无法编译通过,根据编译器提示可以验证 Enum::Tuple 的函数指针身份:
// error[E0271]: type mismatch resolving `<fn(i8, u8) -> tuple_struct::Enum {tuple_struct::Enum::Tuple} as FnOnce<(i8, u8)>>::Output == ()`
// --> src/lib.rs:89:5
// |
// | fn foo2<T1, T2, F: FnOnce(T1, T2)>(op: F) {}
// | -------------- required by this bound in `foo2`
// | foo(Enum::Tuple);
// | foo2(Enum::Tuple); // 作为函数指针,但未实现 FnOnce(T1, T2),无法编译通过,根据编译器提示可以验证 Enum::Tuple 的函数指针身份: ...
// | ^^^^ expected `()`, found enum `tuple_struct::Enum`
}
1
共 4 条评论, 1 页
评论区
写评论感谢楼上各位的指正与补充,我重新调整了一下文章内容
对的。根据你的代码,我又拓展了一下:
我记得在 Rust Book 里面有个例子的代码就用到元组结构体的构造函数性质。
是一个很小的知识点。
--
👇
chirsz-ever: tuple struct 的类型名能当函数用,第二个例子改成:
就能通过编译了。
tuple struct 的类型名能当函数用,第二个例子改成:
就能通过编译了。