7

Hãy tưởng tượng các mục sau đây trong phạm vi:suy luận kiểu trong danh sách đối số kết hợp với setter không làm việc

object Thing { 
    var data: Box[String] = Empty 
} 

def perform[T](setter: Box[T] => Unit) { 
    // doesn't matter 
} 

Sau đây thất bại trong việc biên dịch:

perform(Thing.data = _) 

Các thông báo lỗi là:

<console>:12: error: missing parameter type for expanded function ((x$1) => Thing.data = x$1) 
       perform(Thing.data = _) 
           ^
<console>:12: warning: a type was inferred to be `Any`; this may indicate a programming error. 
       perform(Thing.data = _) 
           ^

Khi biên dịch sau:

perform(Thing.data_=) 

Tôi đã vượt qua vấn đề này bằng cách tạo ra một trừu tượng tốt hơn, nhưng sự tò mò của tôi vẫn còn.

Mọi người có thể giải thích lý do tại sao điều này không?

+0

'T' ra khỏi hư không. Nó có phải là một tham số kiểu cho phương thức 'process' –

Trả lời

3

Hãy mở rộng ra những gì bạn đang làm trong ví dụ đầu tiên:

Thing.data = _ 

là viết tắt cho việc xác định một chức năng ẩn danh, trông giống như:

def anon[T](x: Box[T]) { 
    Thing.data = x 
} 

Vì vậy, khi bạn gọi

perform(Thing.data = _) 

giống với

perform(anon) 

Vấn đề là anonperform mất một tham số kiểu T và tại không có điểm được bạn khai báo T là gì. Trình biên dịch chỉ có thể suy ra các tham số kiểu trong một cuộc gọi hàm từ các đối số đã qua, không phải từ bên trong thân hàm, do đó nó không thể suy ra trong anon rằng T phải là String.

Chú ý rằng nếu bạn gọi

perform[String](Thing.data = _) 

trình biên dịch không có vấn đề bởi vì nó bây giờ biết những gì T nên được, và nếu bạn cố gắng sử dụng bất kỳ loại ngoài chuỗi, bạn sẽ nhận được một lỗi loại không phù hợp, nhưng lỗi xảy ra trong nội dung của chức năng ẩn danh, không phải trên cuộc gọi đến perform.

Tuy nhiên, khi bạn gọi

perform(Thing.data_=) 

bạn đang đi qua các phương pháp Thing.data_=, được một cách rõ ràng định nghĩa là Box[String] => Unit, vì vậy trình biên dịch thể suy luận perform 's kiểu tham số vì nó đến từ một đối số chức năng .

+0

Cảm ơn câu trả lời. Có thể một biểu hiện làm cho nó để [String] không còn cần thiết khi sử dụng 'thực hiện (Thing.data = _)'? – Scoobie

Các vấn đề liên quan