如何在结构方法中为 self 的类型起别名?
How do I alias the type of self in a struct method?
如果我有一个小结构 Test
:
struct Test<T> { a: T }
我希望在 Test
的方法中引用其完整类型:
impl<T> Test<T> {
fn new(a: T) -> Test<T> {
type X = Test::<T>;
println!("{}", std::intrinsics::type_id::<X>());
Test { a: a }
}
}
此 fails 具有 预期的身份,找到 <
,但以下也失败了:
type X = Test;
: 类型参数数量错误:应为 1,找到 0 [E0243]
type X = Test<T>;
: 不能使用外部函数的类型参数;尝试使用本地类型参数代替 并注意 使用未声明的类型名称 T
其实前两者被拒绝是有道理的;不过后者稍微神秘一些。
这是在尝试实现 offset_of!
宏时出现的:offset_of($T:ty, $field:ident)
;该宏运行良好,但是 ty
不接受 Test<T>
(但接受无参数别名)。
有没有办法:
- 为
self
类型创建一个别名,即使是在泛型中?
- 或者,或者,让宏接受
Test<T>
作为 "type" 参数?
注意:如果可能的话,我更喜欢前者的解决方案,因为别名真的很方便。
作为参考,这是我制作的 offset_of
宏:
macro_rules! offset_of(
($T:ty, $field:ident) => {
unsafe {
let exemplar: $T = std::mem::uninitialized();
let base: *const u8 = std::mem::transmute(&exemplar);
let attr: *const u8 = std::mem::transmute(&exemplar.$field);
std::mem::forget(exemplar);
(attr as isize) - (base as isize)
}
}
);
我可能误会你了,但是自我类型已经有了一个别名 — Self
:
#![feature(core)]
struct Test<T> { a: T }
impl<T> Test<T> {
fn new(a: T) -> Test<T>
where T: 'static
{
println!("{}", unsafe { std::intrinsics::type_id::<Self>() });
Test { a: a }
}
}
fn main() {}
我必须添加功能门,使 T
'static
满足 type_id
,并添加一个不安全的块。我希望其中 none 看起来可疑。这似乎也适用于您的别名:
macro_rules! offset_of(
($T:ty, $field:ident) => {
unsafe {
let exemplar: $T = std::mem::uninitialized();
let base: *const u8 = std::mem::transmute(&exemplar);
let attr: *const u8 = std::mem::transmute(&exemplar.$field);
(attr as isize) - (base as isize)
}
}
);
struct Test<T> { a: T, b: T, c: T }
impl<T> Test<T> {
fn new(a: T) -> Test<T>
where T: Copy
{
println!("{}", offset_of!(Self, a));
println!("{}", offset_of!(Self, b));
println!("{}", offset_of!(Self, c));
Test { a: a, b: a, c: a }
}
}
fn main() {
Test::new(1u16);
}
如果我有一个小结构 Test
:
struct Test<T> { a: T }
我希望在 Test
的方法中引用其完整类型:
impl<T> Test<T> {
fn new(a: T) -> Test<T> {
type X = Test::<T>;
println!("{}", std::intrinsics::type_id::<X>());
Test { a: a }
}
}
此 fails 具有 预期的身份,找到 <
,但以下也失败了:
type X = Test;
: 类型参数数量错误:应为 1,找到 0[E0243]
type X = Test<T>;
: 不能使用外部函数的类型参数;尝试使用本地类型参数代替 并注意 使用未声明的类型名称T
其实前两者被拒绝是有道理的;不过后者稍微神秘一些。
这是在尝试实现 offset_of!
宏时出现的:offset_of($T:ty, $field:ident)
;该宏运行良好,但是 ty
不接受 Test<T>
(但接受无参数别名)。
有没有办法:
- 为
self
类型创建一个别名,即使是在泛型中? - 或者,或者,让宏接受
Test<T>
作为 "type" 参数?
注意:如果可能的话,我更喜欢前者的解决方案,因为别名真的很方便。
作为参考,这是我制作的 offset_of
宏:
macro_rules! offset_of(
($T:ty, $field:ident) => {
unsafe {
let exemplar: $T = std::mem::uninitialized();
let base: *const u8 = std::mem::transmute(&exemplar);
let attr: *const u8 = std::mem::transmute(&exemplar.$field);
std::mem::forget(exemplar);
(attr as isize) - (base as isize)
}
}
);
我可能误会你了,但是自我类型已经有了一个别名 — Self
:
#![feature(core)]
struct Test<T> { a: T }
impl<T> Test<T> {
fn new(a: T) -> Test<T>
where T: 'static
{
println!("{}", unsafe { std::intrinsics::type_id::<Self>() });
Test { a: a }
}
}
fn main() {}
我必须添加功能门,使 T
'static
满足 type_id
,并添加一个不安全的块。我希望其中 none 看起来可疑。这似乎也适用于您的别名:
macro_rules! offset_of(
($T:ty, $field:ident) => {
unsafe {
let exemplar: $T = std::mem::uninitialized();
let base: *const u8 = std::mem::transmute(&exemplar);
let attr: *const u8 = std::mem::transmute(&exemplar.$field);
(attr as isize) - (base as isize)
}
}
);
struct Test<T> { a: T, b: T, c: T }
impl<T> Test<T> {
fn new(a: T) -> Test<T>
where T: Copy
{
println!("{}", offset_of!(Self, a));
println!("{}", offset_of!(Self, b));
println!("{}", offset_of!(Self, c));
Test { a: a, b: a, c: a }
}
}
fn main() {
Test::new(1u16);
}