Câu trả lời:
Có một vài điều đang diễn ra.
Đầu tiên, Scala cho phép các dấu chấm và dấu chấm được bỏ qua trong nhiều lệnh gọi phương thức, do đó 20 secondstương đương với 20.seconds()*.
Thứ hai, một "chuyển đổi ngầm" được áp dụng. Vì 20là một Intvà Intkhông có secondsphương thức, trình biên dịch tìm kiếm một chuyển đổi ngầm nhận Intvà trả về một cái gì đó có một secondsphương thức, với tìm kiếm bị giới hạn bởi phạm vi của lệnh gọi phương thức của bạn.
Bạn đã nhập WeatherInt vào phạm vi của bạn. Vì DurationIntlà một lớp ẩn với một Inttham số, hàm tạo của nó định nghĩa một Int => DurationIntchuyển đổi ngầm định . DurationIntcó một secondsphương pháp, vì vậy nó thỏa mãn tất cả các tiêu chí tìm kiếm. Do đó, trình biên dịch viết lại cuộc gọi của bạn là new DurationInt(20).seconds**.
* Ý tôi là điều này lỏng lẻo. 20.seconds()thực sự không hợp lệ vì secondsphương thức không có danh sách tham số và do đó, các parens phải được bỏ qua trong lệnh gọi phương thức.
** Trên thực tế, điều này không hoàn toàn đúng vì DurationIntlà một lớp giá trị, vì vậy trình biên dịch sẽ tránh gói số nguyên nếu có thể.
new DurationInt(20).seconds()khi bạn biết nó hoạt động như thế nào)
secondsphương thức được định nghĩa mà không có parens, vì vậy gọi nó bằng parens là một lỗi.
20.seconds()bằng Scala, chỉ có điều là trình biên dịch đang dịch cuộc gọi theo cách đó. Thật đáng để chỉ ra rằng Scala yêu cầu bạn bỏ qua parens nếu phương thức tương ứng không có danh sách tham số, như trong trường hợp này.
"Phép thuật" đang diễn ra ở đó được gọi là "chuyển đổi ngầm". Bạn đang nhập các chuyển đổi ngầm định và một số trong số chúng xử lý chuyển đổi giữa Int (và Double) thành Thời lượng. Đó là những gì bạn đang đối phó.
import scala.concurrent.duration._giải quyết 20 secondsnhưng thực sự nhập DurationConversionsTrait không? EDIT : Chỉ cần nhận ra những gì họ thực sự nhập khẩu DurationInt. Tôi đoán điều này là do bạn không thể nhập Trait thực tế? Chỉ thực hiện cụ thể của Đặc điểm?