これは確かに可能ですが、あなたは新しい特性と混乱を必要とします。
あなたは抽象
enum VecOrScalar<T> {
Scalar(T),
Vector(Vec<T>),
}
use VecOrScalar::*;
で起動した場合あなたは、あなたがVecOrScalar
でそれをラップし、「隠された」タイプT
を取ることができるので、型変換
T (hidden) -> VecOrScalar<T> -> T (known)
Vec<T> (hidden) -> VecOrScalar<T> -> Vec<T> (known)
を使用するための方法をしたいです実数型T
をmatch
で抽出します。
また
T (known) -> bool = T::Output
Vec<T> (known) -> Vec<bool> = Vec<T>::Output
をしたいが、HKTせずに、これは少しトリッキーです。代わりに、行うことができます
T (known) -> VecOrScalar<T> -> T::Output
Vec<T> (known) -> VecOrScalar<T> -> Vec<T>::Output
パニックする可能性のあるブランチを許可する場合。
形質は、このようにクラス
#[derive(Copy, Clone)]
struct Clf {
x: f64,
}
が最初の2件のBを実装する実装
impl<T> FromVecOrScalar<T> for T {
fn put(self) -> VecOrScalar<T> {
Scalar(self)
}
type Output = bool;
fn get(out: VecOrScalar<bool>) -> Self::Output {
match out {
Scalar(val) => val,
Vector(_) => panic!("Wrong output type!"),
}
}
}
impl<T> FromVecOrScalar<T> for Vec<T> {
fn put(self) -> VecOrScalar<T> {
Vector(self)
}
type Output = Vec<bool>;
fn get(out: VecOrScalar<bool>) -> Self::Output {
match out {
Vector(val) => val,
Scalar(_) => panic!("Wrong output type!"),
}
}
}
と
trait FromVecOrScalar<T> {
fn put(self) -> VecOrScalar<T>;
type Output;
fn get(out: VecOrScalar<bool>) -> Self::Output;
}
あろう牧場:
impl Clf {
fn calc_scalar(self, f: f64) -> bool {
f > self.x
}
fn calc_vector(self, v: Vec<f64>) -> Vec<bool> {
v.into_iter().map(|x| self.calc_scalar(x)).collect()
}
}
あなたがそれを取り出すことができますので、それは、種類
type Output = T::Output;
extern "rust-call" fn call_once(self, (arg,): (T,)) -> T::Output {
派遣最初のボックスのプライベートタイプのアップとT: FromVecOrScalar<f64>
impl<T> FnOnce<(T,)> for Clf
where T: FromVecOrScalar<f64>
{
ためFnOnce
を実装することで、派遣しますenum
を入力し、次にT::get
を入力して再度非表示にします。
match arg.put() {
Scalar(scalar) =>
T::get(Scalar(self.calc_scalar(scalar))),
Vector(vector) =>
T::get(Vector(self.calc_vector(vector))),
}
}
}
その後、成功:コンパイラはこのmalarkyのすべてを見ることができるので
fn main() {
let c = Clf { x : 0.0 };
let v = vec![-1.0, 0.5, 1.0];
println!("{}", c(0.5f64));
println!("{:?}", c(v));
}
、それは実際にcalc_
メソッドを直接呼び出すと基本的に同じアセンブリに完全に離れてコンパイルされます。
しかし、それは書くのがいいとは言いません。このようなオーバーロードは、痛い、壊れやすい、そして確かにBad Idea™です。あなたができることを知っても大丈夫ですが、それをしないでください。
ありがとうございます。 – asdetrefle