我如何从默认方法 return 特殊关联类型?
How can I return specializable associated type from default method?
我 implementing tuple flattening 支持 Rust。它需要转换
((A,B), (C, (D, E)), F)
进入
Cons[
Cons[A, B, Nil],
Cons[
C, Cons[D, E, Nil], Nil
],
F,
Nil
]
我尝试使用专业化,但编译器不喜欢它:
/// For non-tuple types.
impl<T> IntoCons for Val<T> {
default type Out = Cons<T, Nil>;
default fn into_cons(self) -> Cons<T, Nil> {
Cons {
head: self,
tail: Nil,
}
}
}
我该怎么做?任何不使用 unsafe
的替代方案都可以。
完整示例:
#![feature(specialization)]
use std::fmt::{Debug, Display};
pub trait Tr {
type It;
fn it(self) -> Self::It;
}
impl<T> Tr for T
where
T: Debug,
{
default type It = u8;
default fn it(self) -> Self::It {
0
}
}
impl<T> Tr for T
where
T: Debug + Display,
{
type It = u16;
fn it(self) -> Self::It {
0
}
}
fn main() {}
编译器输出:
error[E0308]: mismatched types
--> src/main.rs:17:9
|
16 | default fn it(self) -> Self::It {
| -------- expected `<T as Tr>::It` because of return type
17 | 0
| ^ expected associated type, found integral variable
|
= note: expected type `<T as Tr>::It`
found type `{integer}`
这里的问题是您要返回 Self::It
但给它一个 0。如果有人在 It
为 String
的情况下实现这个会发生什么?由于无法证明这始终是一个数字,因此您要么需要特征绑定,要么更改方法签名。
一种可行的方法是这样的:
pub trait Tr {
type It: Default;
fn it(self) -> Self::It;
}
impl<T> Tr for T
where
T: Debug,
{
default type It = u8;
default fn it(self) -> Self::It {
Default::default()
}
}
我 implementing tuple flattening 支持 Rust。它需要转换
((A,B), (C, (D, E)), F)
进入
Cons[
Cons[A, B, Nil],
Cons[
C, Cons[D, E, Nil], Nil
],
F,
Nil
]
我尝试使用专业化,但编译器不喜欢它:
/// For non-tuple types.
impl<T> IntoCons for Val<T> {
default type Out = Cons<T, Nil>;
default fn into_cons(self) -> Cons<T, Nil> {
Cons {
head: self,
tail: Nil,
}
}
}
我该怎么做?任何不使用 unsafe
的替代方案都可以。
完整示例:
#![feature(specialization)]
use std::fmt::{Debug, Display};
pub trait Tr {
type It;
fn it(self) -> Self::It;
}
impl<T> Tr for T
where
T: Debug,
{
default type It = u8;
default fn it(self) -> Self::It {
0
}
}
impl<T> Tr for T
where
T: Debug + Display,
{
type It = u16;
fn it(self) -> Self::It {
0
}
}
fn main() {}
编译器输出:
error[E0308]: mismatched types
--> src/main.rs:17:9
|
16 | default fn it(self) -> Self::It {
| -------- expected `<T as Tr>::It` because of return type
17 | 0
| ^ expected associated type, found integral variable
|
= note: expected type `<T as Tr>::It`
found type `{integer}`
这里的问题是您要返回 Self::It
但给它一个 0。如果有人在 It
为 String
的情况下实现这个会发生什么?由于无法证明这始终是一个数字,因此您要么需要特征绑定,要么更改方法签名。
一种可行的方法是这样的:
pub trait Tr {
type It: Default;
fn it(self) -> Self::It;
}
impl<T> Tr for T
where
T: Debug,
{
default type It = u8;
default fn it(self) -> Self::It {
Default::default()
}
}