Duy trì API so với sử dụng thành ngữ trong một cổng


12

Tôi đang làm việc trên một cổng từ Python sang Rust và chạy vào một số mã không thể được thể hiện một cách tự nhiên trong Rust như họ có thể trong Python.

Một trường hợp này là sử dụng các tham số mặc định:

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

Trong Rust, bạn có thể thực hiện điều này bằng cách sử dụng trình xây dựng:

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,
    }
  }
}

Để sử dụng lớp trong Python, chỉ cần:

foo = Foo("Hello, World!")

Tuy nhiên, trong Rust, bạn sẽ cần phải viết một cái gì đó như:

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

Điều này dẫn đến câu hỏi: tốt hơn là duy trì API cho một cổng, hay tốt hơn là sử dụng các thành ngữ của ngôn ngữ chuyển? Có phụ thuộc vào mức độ nổi tiếng của API bắt đầu không?


2
API của một lớp là cách bạn sử dụng nó, chứ không phải cách nó được thể hiện trong mã. Vì vậy, bản dịch đó có một ABI khác biệt rõ ràng và đơn giản không thể chấp nhận được.
Ded repeatator

Nơi nào nói rằng đó là thành ngữ Rust?
Nadir Sampaoli

Tôi xin lỗi, tôi đã hiểu lầm. Bạn đã đăng một số mã Rust, cùng với một vấn đề nan giải: thời tiết bạn duy trì API cho một cổng hoặc bạn sẽ sử dụng thành ngữ của ngôn ngữ chuyển . Mã đó không giống như một trong những trường hợp đó. Nếu đây là giải thích chính xác, mục đích của mẫu mã đó là gì? Nó mô tả cái gì và nó liên quan như thế nào với câu hỏi thực tế?
Nadir Sampaoli

Câu trả lời:


18

Bạn muốn ý tưởng của bạn được thể hiện rõ ràng bằng ngôn ngữ lưu trữ chúng. Điều đó có nghĩa là sử dụng thành ngữ ngôn ngữ máy chủ.

Lấy thư viện Underscore phổ biến: jslua . Cổng lua có chức năng tương đương với hầu hết các phần . Nhưng khi nó phù hợp, việc triển khai hơi khác một chút. Ví dụ:

_.toArray()

trở thành

_.to_array()

Sự thay đổi này làm cho tên hàm cảm thấy tự nhiên hơn đối với các lập trình viên Lua.

Tương tự, _.each () yêu cầu một đối tượng, mảng hoặc một thứ gì đó giống như mảng trong JavaScript, nhưng _.each () trong Lua cũng có thể có một trình vòng lặp - một cơ chế không có sẵn trong JavaScript khi thư viện Underscore ban đầu đã được tạo ra.

Tác giả Lua đã dịch một cách hợp lý những gì tác giả ban đầu dự định nếu họ đã viết nó bằng Lua. Đó là chìa khóa. Tự hỏi bản thân về ý định ban đầu và sau đó thực hiện ý định đó bằng ngôn ngữ bạn chọn - thành ngữ và tất cả. Tùy thuộc vào nguồn và ngôn ngữ đích, điều này có thể có nghĩa là thêm, chỉnh sửa hoặc xóa các tính năng.

Hãy nhớ rằng người dùng ngôn ngữ chéo sẽ rất hiếm. Hầu hết người dùng sẽ sử dụng ngôn ngữ này hoặc ngôn ngữ khác. Đối với họ, sự khác biệt không quan trọng. Nếu ai đó sử dụng cả hai, họ có thể đủ tinh vi để đánh giá cao bản dịch của bạn. Nó không khác gì dịch ngôn ngữ nói. Một số ý tưởng không thể dịch trực tiếp. Các dịch giả tốt nhất bám sát ý định của bản gốc, không phải là một bản dịch từng chữ từng chữ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.