2011-10-06 38 views
33

bất cứ ai có thể vui lòng giải thích cho tôi tại sao tôi có thể làm:Sử dụng _ trong các hàm lambda scala

a.mapValues(_.size) 

thay vì

a.mapValues(x => x.size) 

nhưng tôi không thể làm

a.groupBy(_) 

thay của một số

a.groupBy(x => x) 
+11

Bạn có thể sử dụng 'identity' trong trường hợp bạn cần hàm 'x => x': 'a groupBy identity' – incrop

+2

@incrop Cảm ơn bạn đã tip, tôi không bao giờ nhận thấy chức năng nhận dạng đã có trong' Predef' ... – paradigmatic

Trả lời

15

Nó không phải là dễ dàng để nhìn thấy nó ở đây:

a.groupBy(_) 

Nhưng nó dễ dàng hơn để nhìn thấy nó trong một cái gì đó như thế này:

a.mkString("<", _, ">") 

tôi đang áp dụng một phần phương pháp/chức năng. Tôi đang áp dụng nó cho một số thông số (người đầu tiên và cuối cùng), và rời khỏi tham số thứ hai không được áp dụng, vì vậy tôi nhận được một chức năng mới như thế này:

x => a.mkString("<", x, ">") 

Ví dụ đầu tiên chỉ là một trường hợp đặc biệt nơi tham số duy nhất được áp dụng một phần. Tuy nhiên, khi bạn sử dụng dấu gạch dưới trên một biểu thức, nó là viết tắt của các tham số vị trí trong một hàm ẩn danh.

a.mapValues(_.size) 
a.mapValues(x => x.size) 

Rất dễ nhầm lẫn, vì cả hai đều dẫn đến chức năng ẩn danh. Trên thực tế, có dấu gạch dưới thứ ba được sử dụng để chuyển đổi phương thức thành giá trị phương thức (cũng là một hàm ẩn danh), chẳng hạn như:

39

Khi bạn viết a.groupBy(_) trình biên dịch hiểu nó như là một chức năng ẩn danh:

x => a.groupBy(x) 

Theo Scala Thông số kỹ thuật §6.23, một placeholder gạch trong một biểu thức được thay thế bằng một tham số ẩn danh. Vì vậy:

  • _ + 1 được mở rộng để x => x + 1
  • f(_) được mở rộng để x => f(x)
  • _ không được mở rộng bởi chính nó (giữ chỗ không phải là một phần của bất kỳ biểu hiện).

Biểu thức x => a.groupBy(x) sẽ gây nhầm lẫn trình biên dịch vì không thể suy ra loại x. Nếu a là một số bộ sưu tập các loại E yếu tố, sau đó trình biên dịch hy vọng x là một chức năng của loại (E) => K, nhưng gõ K không thể được suy ra ...

+0

Hmmm ... Tại sao? :-) –

+0

@HugoSFerreira Câu trả lời được cập nhật với giải thích. – paradigmatic

+0

Cảm ơn bạn. Nhưng, tại sao không phải là 'a.mapValues ​​(_. Size)' được hiểu là 'x => a.mapValues ​​(x.size)'? –

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