Nói rằng tôi có một lớp đơn giản như thế nàykiểu suy luận của tham số ngầm generic từ kiểu trả
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
Khi tuyên bố val f2
, trình biên dịch có thể suy luận rằng các loại tham số ngầm của chức năng f
là Int
vì đó loại giống với loại kết quả và loại kết quả cần phải khớp với loại giá trị f2
, là Int
.
Tuy nhiên, ném một Ordering[A]
vào trộn:
def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()
kết quả do lỗi biên dịch này:
Ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and method $conforms in object Predef of type [A]=> <:<[A,A] match expected type A
Nếu tôi thêm các loại thông tin khi gọi f()
, nó biên dịch:
val f2: Int = f[Int]()
Trước tiên, tôi gặp phải trường hợp có đặt hàng ngầm định d Tôi nghĩ rằng nó phải làm với Scala suy luận từ trái qua phải; Tôi nghĩ rằng không thể đối sánh loại trả về trước tiên và rồi suy ra loại thông số (ẩn) của f
. Nhưng sau đó tôi đã thử các trường hợp mà không có trật tự ngầm và thấy rằng nó hoạt động - nó suy ra rằng f
phải được tham số bởi Int
vì loại trả về phải là Int
(vì f2
là Int
).
Lưu ý rằng nếu chúng ta loại bỏ implicit a: A
và để lại chỉ là tham số ngầm đặt hàng, lỗi vẫn còn, nhưng trở nên
Diverging implicit expansion for type Ordering[A] starting with method Tuple9 in object Ordering.
Một lần nữa, thêm tham số kiểu để nó trở thành val f2: Int = f[Int]()
giúp.
Điều gì đang xảy ra? Tại sao trình biên dịch suy ra tham số A
phải là Int
, nhưng không phải tham số Ordering[A]
đó phải là Ordering[Int]
?
Có vẻ như [SI-8541] (https://issues.scala-lang.org/browse/SI-8541) –