如果我有一个小结构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>
作为“类型”参数?注意:如果可能的话,我更喜欢前者的解决方案,因为别名非常方便。
供参考,这是我制作的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)
}
}
);
答案 0 :(得分:2)
我可能误解了你,但已经有了自我类型的别名 - 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
,并添加不安全的阻止。我希望这一切看起来都不可疑。这似乎与您的别名一起使用:
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);
}