我想要一些类似功能绑定的可选特征。ifT实现该类型的地方 - 做一些事情。
fn test<T: Eq + ?Debug>(a:T, b:T){
if a!=b{
println!("Not equal!");
if (T impl Debug){
println!("{:?} != {:?}", a, b);
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如@user4815162342 评论的那样,使用专业化,这是可能的。
我将提供与他们在评论中指定的方法略有不同的方法,以保持与if ... { ... }原始代码中相同的设置。
这个想法是拥有一个AsMaybeDebug具有关联 type 的特征Debug,它总是实现Debug一个从 到 的&Self函数Option<&Self::Debug>:
trait AsMaybeDebug {
type Debug: Debug;
fn as_maybe_debug(&self) -> Option<&Self::Debug>;
}
Run Code Online (Sandbox Code Playgroud)
之后,我们为 all 创建一个默认的 impl T,调试类型为!never 类型,并且始终返回None。
impl<T> AsMaybeDebug for T {
default type Debug = !;
default fn as_maybe_debug(&self) -> Option<&Self::Debug> {
None
}
}
Run Code Online (Sandbox Code Playgroud)
Debug您可以选择始终实现但仍返回 的任何类型,而不是 never 类型None。
之后我们专门T: Debug返回Self:
impl<T: Debug> AsMaybeDebug for T {
type Debug = Self;
fn as_maybe_debug(&self) -> Option<&Self::Debug> {
Some(self)
}
}
Run Code Online (Sandbox Code Playgroud)
最后test我们只需调用as_maybe_debug并检查是否T: Debug
impl<T: Debug> AsMaybeDebug for T {
type Debug = Self;
fn as_maybe_debug(&self) -> Option<&Self::Debug> {
Some(self)
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在游乐场中检查它是否有效,以及生成的程序集是否test_non_debug没有任何调试调用,只有对std::io::_print.
不幸的是,调用后无法检索原始内容a或b内部内容。ifas_maybe_debug
这是由于<Self as AsMaybeDebug>::Debug无法转换回Self. 这个问题可以修复,但并不容易,因为它需要标准库的更新。
要求AsMaybeDebug::Debug: AsRef<Self>不起作用有两个原因:
impl<T> AsRef<T> for T,我认为这是由于专业化仍然不完整。impl<T> AsRef<T> for !。不确定这个实现是否可以在专业化的情况下实现,但这是必需的。另外,虽然可能specialization不健全,但我相信该特征及其隐含不能用于不健全,您需要一个特定的设置才能从中生成不健全,而这是所缺乏的。