APIの維持とポートでのイディオムの使用


12

私はPythonからRustへの移植に取り組んでおり、RustでPythonほど自然に表現できないコードに遭遇しました。

これの1つのケースは、デフォルトのパラメーターを使用することです。

class Foo:
  def __init__(self, a="Hello"):
    self._a = a

Rustでは、ビルダーを使用してこれを実装できます。

struct FooBuilder {
  a: &'static str,
}

struct Foo {
  _a: &'static str
}

impl FooBuilder {
  fn new() -> FooBuilder {
    FooBuilder {
      a: "Hello",
    }
  }

  fn change_a(self, new_a: &'static str) -> FooBuilder {
    FooBuilder {
      a: new_a,
      ..self
    }
  }

  fn build(self) -> Foo {
    Foo {
      _a: self.a,
    }
  }
}

Pythonでクラスを使用するには、次のようにします。

foo = Foo("Hello, World!")

ただし、Rustでは、次のように記述する必要があります。

let foo = FooBuilder::new().change_a("Hello, World!").build();

これは、ポートのAPIを維持する方が良いのか、それとも移植言語のイディオムを使用する方が良いのかという疑問につながります。APIがどの程度有名であるかにかかっていますか?


2
クラスのAPIは、それをコードで表現する方法ではなく、使用方法です。そのため、その翻訳はまったく異なっており、受け入れがたいほど厄介なABIを持っています。
デュプリケータ

それは慣用的なRustだとどこで言われていますか?
ナディールサンパオリ

ごめんなさい、誤解し​​たに違いありません。いくつかのRustコードと、ジレンマを投稿しました。天気は、ポートのAPIを維持する、移植言語のイディオムを使用するかです。そのコードは、これらのケースのいずれにも似ていません。これが正しい解釈である場合、そのコードサンプルの目的は何ですか?それは何を説明していて、実際の質問とどのように関係していますか?
ナディールサンパオリ

回答:


18

アイデアをホストする言語で明確に表現する必要があります。つまり、ホスト言語のイディオムを使用します。

人気のあるアンダースコアライブラリであるjsluaを使用します。luaポートはほとんどの部分で機能的に同等です。しかし、適切な場合、実装はわずかに異なります。例えば:

_.toArray()

になる

_.to_array()

この変更により、関数名はLuaプログラマーによりネイティブに感じられます。

同様に、_.eachは()オブジェクト、配列、またはJavaScriptの配列のようなものを必要としますが、_.each() Luaの中にも、イテレータを取ることができます-オリジナルアンダーライブラリJavaScriptで利用できなかったメカニズムを作成されました。

Luaの作者は、元の作者 Luaで書いた場合に意図していたものを賢明に翻訳しました。それが鍵です。元の意図について自問し、その意図を選択した言語(イディオムなど)に実装します。ソース言語とターゲット言語に応じて、これは機能の追加、編集、または削除を意味します。

言語間ユーザーはまれであることを忘れないでください。ほとんどのユーザーは、いずれかの言語を使用します。彼らにとって、違いは重要ではありません。誰かが両方を使用している場合、おそらくあなたの翻訳を評価するのに十分なほど洗練されています。話し言葉の翻訳と同じです。一部のアイデアは直接翻訳できません。最高の翻訳者は、運命の単語ごとのリテラル翻訳ではなく、オリジナルの意図に固執します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.