Rust 处理f64或Complex64返回类型。仿制药?任何一个
我有一个运行正常的Rust程序,它使用实数双精度(Rust 处理f64或Complex64返回类型。仿制药?任何一个,rust,generic-programming,either,Rust,Generic Programming,Either,我有一个运行正常的Rust程序,它使用实数双精度(f64)作为底层类型,并希望扩展系统,使其也可以处理复杂值(num::complex::Complex64) (简化示例)函数采用一些配置结构config,并根据该输入在索引idx处生成一个潜在值: fn potential(config: &Config, idx: &Index3) -> Result<f64, Error> { let num = &config.grid.size;
f64
)作为底层类型,并希望扩展系统,使其也可以处理复杂值(num::complex::Complex64
)
(简化示例)函数采用一些配置结构config
,并根据该输入在索引idx
处生成一个潜在值:
fn potential(config: &Config, idx: &Index3) -> Result<f64, Error> {
let num = &config.grid.size;
match config.potential {
PotentialType::NoPotential => Ok(0.0),
PotentialType::Cube => {
if (idx.x > num.x / 4 && idx.x <= 3 * num.x / 4) &&
(idx.y > num.y / 4 && idx.y <= 3 * num.y / 4) &&
(idx.z > num.z / 4 && idx.z <= 3 * num.z / 4) {
Ok(-10.0)
} else {
Ok(0.0)
}
}
PotentialType::Coulomb => {
let r = config.grid.dn * (calculate_r2(idx, &config.grid)).sqrt();
if r < config.grid.dn {
Ok(-1. / config.grid.dn)
} else {
Ok(-1. / r)
}
}
}
}
此函数是我的程序中的早期入口点,它填充ndarray::Array3
;目前,我正在对许多类型为ndarray::Array3
的变量进行操作,因此我需要概括整个程序,而不仅仅是这个函数
如何根据config
的输入扩展此程序以使用这两种类型?此结构来自解析磁盘上的配置文件,并将匹配许多PotentialType::Complex*
值
我知道有两种可能的选择,但不确定其中一种是否符合我的标准
Left
表示实数,返回Right
表示复数;然后使用附加逻辑在其他函数中分别处理这些值如果你有任何其他的建议,我很乐意听听 可能会有很多代码更改,但使用泛型参数可能是最灵活的方法,并且不会影响性能。传递
enum
会降低性能,部分原因是enum会更大(较大变量的大小加上区分它们的标记),部分原因是必须经常检查enum变量
有一件事可能会变得麻烦,那就是约束类型参数的特性列表可能很长。这可以在impl
级别上完成,而不是在每个函数上完成,以避免重复。目前还没有一种方法来为一组特征命名,这将使其更符合人体工程学,但有一种被认可的方法
我做了一个非常好的决定。那是一年多以前的事了,从那以后,Rust和那个库都发生了很大的变化,但是快速浏览一下commit应该仍然可以让您了解到所需的变化量
这是同一(重命名)实现的名称:
impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
where T: Copy + Clone +
Add<T, Output=T> +
Sub<T, Output=T> +
Mul<T, Output=T> +
Div<T, Output=T> +
Neg<Output=T> +
ApproxEq<T> +
PartialOrd +
Trig +
One + Zero {
// methods of TypedTransform3D defined here...
}
impl-TypedTransform3D
其中T:Copy+Clone+
加+
潜艇+
骡子+
Div+
负数+
近似+
游击队+
触发+
一加零{
//此处定义的类型数据传输M3D的方法。。。
}
一些特性(
Trig
,One
,Zero
)实际上是,因为它们不在标准库中。可能会有很多代码更改,但使用通用参数可能是最灵活的方法,并且不会影响性能。传递enum
会降低性能,部分原因是enum会更大(较大变量的大小加上区分它们的标记),部分原因是必须经常检查enum变量
有一件事可能会变得麻烦,那就是约束类型参数的特性列表可能很长。这可以在impl
级别上完成,而不是在每个函数上完成,以避免重复。目前还没有一种方法来为一组特征命名,这将使其更符合人体工程学,但有一种被认可的方法
我做了一个非常好的决定。那是一年多以前的事了,从那以后,Rust和那个库都发生了很大的变化,但是快速浏览一下commit应该仍然可以让您了解到所需的变化量
这是同一(重命名)实现的名称:
impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
where T: Copy + Clone +
Add<T, Output=T> +
Sub<T, Output=T> +
Mul<T, Output=T> +
Div<T, Output=T> +
Neg<Output=T> +
ApproxEq<T> +
PartialOrd +
Trig +
One + Zero {
// methods of TypedTransform3D defined here...
}
impl-TypedTransform3D
其中T:Copy+Clone+
加+
潜艇+
骡子+
Div+
负数+
近似+
游击队+
触发+
一加零{
//此处定义的类型数据传输M3D的方法。。。
}
其中一些特征(
Trig
,One
,Zero
)实际上是,因为它们不在标准库中。这个问题的“建议”性质很棘手(我认为它触及了“太宽”的边界)。特别是,您列出了两个选项,但没有显示将它们转换为代码的尝试。即使我们愿意,我们也无法展示“如何降低复杂性”。显示更多的代码可以提高问题的质量。无论如何,我们已经可以在表中列出一些事实:即使函数返回一个结果
(其中T
可以是f64
,Complex64
,…),我们也不能在config
中选择T
,有运行时字段。在最坏的情况下,您可能需要2个函数实例。我们不能在config
中选择t
…您可能需要2个函数实例。这个问题的“建议”性质很棘手(在我看来,它触及了“太宽”的边界)。特别是,您列出了两个选项,但没有显示将它们转换为代码的尝试。即使我们愿意,我们也无法展示“如何降低复杂性”。显示更多的代码可以提高问题的质量。无论如何,我们已经可以在表中列出一些事实:即使函数返回一个结果
(其中T
可以是f64
,Complex64
,…),我们也不能在config
中选择T
,有运行时字段。在最坏的情况下,您可能需要2个函数实例。我们无法在config
中选择t
…您可能需要2个函数实例。我将查看您的代码,并尝试以类似的方式获取我的MWE。我会把你的答案标记为正确的