2010-08-16 44 views
7
List("This","is","Scala").foreach(a => print(a+" ")) 

biên dịch tốt, nhưngloại scala suy luận với _ giữ chỗ

List("This","is","Scala").foreach(print(_+" ")) 

thất bại phàn nàn về thiếu loại tham số. Tôi không thể hiểu tại sao nó thất bại.

CHỈNH SỬA: Ý tôi là in không in - không phải là nó tạo ra sự khác biệt hợp lý.

+2

Xem http://stackoverflow.com/questions/2173373/scala-foreach-strange-behaviour/2176548#2176548 để biết câu trả lời chi tiết hơn. – huynhjl

Trả lời

7

Vấn đề là điều này

List("This","is","Scala").foreach(print(_+" ")) 

không tương đương với

List("This","is","Scala").foreach(a => print(a+" ")) 

nhưng đến

List("This","is","Scala").foreach(print(a => a+" ")) 

Bây giờ, chúng ta hãy xem các loại chữ ký của foreach:

def foreach [B] (f: (A) ⇒ B) : Unit 

nơi A là tham số kiểu của List riêng của mình. Vì chúng ta có một List[String], trình biên dịch biết người ta phải vượt qua foreach một Function[String, B].

Trong a => print(a+" ") loại a đã được biết rồi: String.

Trong print(a => a+" ") có sự cố, vì print không phải là Function. Tuy nhiên, trình biên dịch đã không xem xét điều đó - nó vẫn đang cố gắng biên dịch a => a+" ". Vì vậy, chúng ta hãy nhìn vào các loại Predef.print:

def print (x: Any) : Unit 

Vì vậy a => a+" " phải loại Any, trong đó, tất nhiên, có nghĩa là nó có thể là bất cứ điều gì. Nó không giúp trình biên dịch trong việc xác định loại a là gì. Mà không thực sự quan trọng, bởi vì bạn không muốn in một Function ở nơi đầu tiên.

6

Scala đọc (_+" ")x => x+" ". Nhưng println không chứa bất kỳ thông tin loại nào để giúp trình biên dịch đoán loại x có thể là gì, do đó, nó cho lỗi đó.

Điều bạn muốn làm là nhận thấy rằng println không hoạt động và recurse ngược lại và thử lại lần nữa cho foreach. Nhưng nó không thể làm điều đó: println có thể lấy bất kỳ đối số nào, kể cả hàm, vì vậy x => x+" " là một điều hoàn toàn hợp lệ cho println để cố gắng in.

(Và ngay cả trong trường hợp nó có thể về mặt lý thuyết quay lại, nó thường không.)

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