Ký hiệu Scala infix


12

Có thể gọi một phương thức bằng cách sử dụng ký hiệu infix?

Ví dụ, trong Haskell, tôi có thể viết hàm sau:

x `isAFactorOf` y = x % y == 0

và sau đó sử dụng nó như:

if 2 `isAFactorOf` 10 ...

Mà trong một số trường hợp cho phép mã rất dễ đọc. Có bất cứ điều gì tương tự như thế này có thể có trong Scala? Tôi đã tìm kiếm "ký hiệu Scala infix", nhưng thuật ngữ đó dường như có ý nghĩa khác trong Scala.

Câu trả lời:


15

Bắt đầu với phiên bản 2.10, Scala đã giới thiệu các Lớp ẩn để xử lý chính xác vấn đề này.

Điều này sẽ thực hiện chuyển đổi ngầm định trên một loại nhất định sang một lớp được bao bọc, có thể chứa các phương thức và giá trị của riêng bạn.

Trong trường hợp cụ thể của bạn, bạn sẽ sử dụng một cái gì đó như thế này:

implicit class RichInt(x: Int) {
  def isAFactorOf(y: Int) = x % y == 0
}

2.isAFactorOf(10)
// or, without dot-syntax
2 isAFactorOf 10

Lưu ý rằng khi được biên dịch, điều này sẽ kết thúc giá trị thô của chúng tôi thành a RichInt(2). Bạn có thể giải quyết vấn đề này bằng cách khai báo RichInt của bạn là một lớp con của AnyVal:

implicit class RichInt(val x: Int) extends AnyVal { ... }

Điều này sẽ không gây ra quyền anh, nhưng nó hạn chế hơn một lớp ngầm điển hình. Nó chỉ có thể chứa các phương thức, không phải giá trị hoặc trạng thái.


2
Có lẽ bạn nên đề cập rằng các lớp ẩn không thể là cấp cao nhất, vì vậy lớp ẩn sẽ cần được xác định cục bộ.
Carcigenicate

3

Về cơ bản, trong Scala, bạn không thể gọi một hàm theo cách kết hợp, nhưng bạn có thể định nghĩa một phương thức trên một kiểu, mà đối số bên trái có thể được chuyển đổi thành ngầm định. Vì vậy, với ví dụ của bạn, bạn có thể định nghĩa một lớp có phương thức isAFactorOf (lấy một Int) và chỉ ra rằng một Int có thể được chuyển đổi hoàn toàn thành một thể hiện của lớp này.

Nếu bạn nhìn vào câu trả lời này /programming//a/3119671 cho một câu hỏi khác, bạn sẽ thấy cú pháp trong Scala hoạt động tương đương.


Thật đáng để chỉ ra rằng các phiên bản mới của Scala có cấu trúc rõ ràng cho điều này, mà câu trả lời được liên kết không giải quyết : implicit class RichInt(i: Int) { def square() = i * i }.
KChaloux
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.