我想要一些类似功能绑定的可选特征。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
内部内容。if
as_maybe_debug
这是由于<Self as AsMaybeDebug>::Debug
无法转换回Self
. 这个问题可以修复,但并不容易,因为它需要标准库的更新。
要求AsMaybeDebug::Debug: AsRef<Self>
不起作用有两个原因:
impl<T> AsRef<T> for T
,我认为这是由于专业化仍然不完整。impl<T> AsRef<T> for !
。不确定这个实现是否可以在专业化的情况下实现,但这是必需的。另外,虽然可能specialization
不健全,但我相信该特征及其隐含不能用于不健全,您需要一个特定的设置才能从中生成不健全,而这是所缺乏的。