私は実際の倍数(f64
)を基礎とするタイプとして機能するRustプログラムを持っており、複雑な値(num::complex::Complex64
)も処理できるようにシステムを拡張したいと考えています。f64またはComplex64の戻り値の型の処理。ジェネリック?どちらか?
A(例削減)関数は、いくつかのコンフィギュレーション構造体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)
}
}
}
}
今Complex64
を返すComplexCoulomb
一致を追加します値:
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*
値の数と一致します。
私は2つの可能なオプションを認識していますが、いずれかの条件に合致するかどうかはわかりません。
- 使用Eitherに似たものと実数と複素数のための
Right
ためLeft
を返します。追加ロジックを使用して、他の機能で値を個別に処理します。 - ジェネリックタイプを使用してください。これは私があまり前にやったことではないし、generalisation over many typesは私の現在のコードベースの複雑な変更の公正な塊のように思える。複雑さを減らす方法はありますか?
他にも提案がありましたら、聞いてみてください!
この質問は、その「提案」の性質(私の意見では「あまりにも広い」境界線に当たっている)にとっては難しいことです。特に、コードに変換しようとする試みを示さずに、2つのオプションをリストしました。たとえ欲しかったとしても、「複雑さを減らす方法」を示すことはできませんでした。いくつかのコードを表示すると、質問の品質が向上する可能性があります。たとえ関数が 'Result'(ここで 'T'は' f64'、 'Complex64'、...)を返すとしても、実行時フィールドを持つことはできません'config'で' T'を選択します。最悪の場合、2つの関数インスタンスが必要になることがあります。 –
_weは 'config'にランタイムフィールドを持つことができません' T'を選択... 2つの関数インスタンスが必要かもしれません_ < - これは実際には私の実際の答えかもしれません。他のオプションがまだ適合していれば、私の質問をすぐに編集して編集します。ありがとう! – Geodesic