Sau đây là một phiên bản đơn giản của vấn đề thực sự của tôi:Scala: lỗi trong tham số ngầm
class Z[T]
object E extends Enumeration {
implicit val z = new Z[Value]
val X, Y = Value
}
implicit def f[T : Z] = (getter: T) => 0
implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0
def e: Option[E.Value] = null
val b: Int = e
này hoạt động, với b ngầm chuyển đổi sang o (e) (f (E.z)). Nhưng với những thay đổi nhỏ sau:
implicit def f[T : Z] = (setter: T => Unit) => 0
implicit def o[T](v: Option[T])(implicit toInt: (T => Unit) => Int) = 0
nó vẫn thất bại tìm E.z giá trị tiềm ẩn thích hợp mặc dù không có sự khác biệt cần thiết từ mã ban đầu, trong khi chuyển đổi rõ ràng bằng tay để o (e) (f (E.z)) vẫn hoạt động.
Tôi biết việc triển khai thông số ngầm chưa hoàn tất và vẫn còn nhiều vấn đề chưa được giải quyết. Nếu đây là một trong số họ, tôi muốn báo cáo cho những người đóng góp Scala. Vì vậy, câu hỏi của tôi là, a) đây thực sự là một lỗi? b) nếu vậy, ở đâu và làm thế nào tôi có thể nộp một lỗi để nó có thể được sửa trong tương lai?
CẬP NHẬT câu trả lời
Travis' làm việc như một nét duyên dáng! Bằng cách này, các mã trên là một cách giải quyết cho vấn đề ban đầu của tôi:
implicit object E extends Enumeration { val X, Y = Value }
implicit object F extends Enumeration { val X, Y = Value }
implicit def f[T <: Enumeration](getter: T#Value)(implicit e: T) = 0
implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0
val b: Int = Some[E.Value](null)
Trong mã này, tình hình là cách khác xung quanh: nó hoạt động với phiên bản setter nhưng không phải với phiên bản getter đơn giản hơn. Trình biên dịch phàn nàn rằng nó gây nhầm lẫn cho dù sử dụng E hoặc F là tham số ngầm định mặc dù sử dụng F không thực sự biên dịch cũng không có ý nghĩa. Tôi quản lý để làm cho nó hoạt động bằng cách thực hiện một điều tương tự:
implicit def f[S <% T => T, T <: Enumeration](getter: T#Value)(implicit e: T) = 0
Điều này hoạt động, và mặc dù tôi bằng cách nào đó có thể làm việc, tôi vẫn không hiểu được logic đằng sau ma thuật này.
Thú vị. Chạy lệnh này với '-Xlog-implicits', có vẻ như' T' trong 'f [T: Z]' không được suy ra như 'E.Value'. Do đó điều này làm việc: 'val b: Int = o (e) (f [E.Value])' nhưng điều này không: 'val b: Int = o (e) (f)'. – gourlaysama