У меня есть работающая программа на Rust, использующая реальные двойники (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)
}
}
}
}
Теперь я хочу добавить совпадение ComplexCoulomb
, которое возвращает значение Complex64
:
PotentialType::ComplexCoulomb => {
let r = config.grid.dn * (calculate_r2(idx, &config.grid)).sqrt();
if r < config.grid.dn {
Ok(Complex64::new(-1. / config.grid.dn, 1.))
} else {
Ok(Complex64::new(-1. / r, 1.))
}
}
Эта функция является ранней точкой входа в мою программу, которая заполняет ndarray::Array3
; в настоящее время я работаю с несколькими переменными типа ndarray::Array3<f64>
, поэтому мне нужно обобщить всю программу, а не только эту функцию.
Как я могу расширить эту программу, чтобы использовать оба типа на основе входных данных от config
? Эта структура получена в результате синтаксического анализа файла конфигурации на диске и будет соответствовать ряду значений PotentialType::Complex*
.
Я знаю о двух возможных вариантах, но не уверен, соответствует ли один из них моим критериям.
- Используйте что-то похожее на Either и возвращайте
Left
для реального иRight
для сложного; затем используйте дополнительную логику для отдельной обработки значений в других функциях. - Используйте универсальные типы. Это не то, чем я занимался раньше, и обобщение по многим типам кажется довольно сложным изменением моей текущей кодовой базы. Есть ли способ уменьшить сложность здесь?
Если у вас есть другие предложения, я хотел бы услышать их!
Result<T, Error>
(гдеT
может бытьf64
,Complex64
, ...), у нас не может быть поля времени выполнения вconfig
, выбирающегоT
. В худшем случае вам может понадобиться 2 экземпляра функции. - person E_net4 the curator   schedule 28.05.2017config
, выбравT
... вам может понадобиться 2 экземпляра функции ‹- Это действительно может быть мой ответ на самом деле. Изучу это и скоро отредактирую свой вопрос, если другие варианты все еще подходят. Спасибо! - person Geodesic   schedule 28.05.2017