8

Trong khi tạo bản đồ chuỗi thành các hàm một phần, tôi gặp phải hành vi không mong muốn. Khi tôi tạo ra một phần chức năng như một yếu tố bản đồ nó hoạt động tốt. Khi tôi phân bổ cho một val nó gọi thay vào đó. Cố gắng gọi kiểm tra tạo ra một lỗi. Đây có phải là dự kiến ​​không? Tôi có làm gì đó ngu ngốc không? Hãy chú thích số check() để xem lời gọi. Tôi đang sử dụng scala 2.7.7Khi nào một hàm scala một phần không phải là một phần chức năng?

def PartialFunctionProblem() = { 
    def dream()() = { 
     println("~Dream~"); 
     new Exception().printStackTrace() 
    } 
    val map = scala.collection.mutable.HashMap[String,()=>Unit]() 
    map("dream") = dream()  // partial function 
    map("dream")()    // invokes as expected 
    val check = dream()   // unexpected invocation 
    check()      // error: check of type Unit does not take parameters 
} 
+0

Cảm ơn sự giúp đỡ. Khi tôi thay thế giấc mơ của tôi() các cuộc gọi với giấc mơ() _ nó cư xử như tôi mong đợi. Tôi sẽ đi ra ngoài và đọc thêm về PartialFunctions vì vậy tôi không sử dụng sai thuật ngữ một lần nữa. –

Trả lời

12

Để thuận tiện, Scala cho phép bạn bỏ qua dấu ngoặc rỗng khi gọi một phương pháp, nhưng nó đủ thông minh để thấy rằng các loại dự kiến ​​trong trường hợp đầu tiên là ()=>Unit, vì vậy nó không loại bỏ tất cả các parens cho bạn; thay vào đó, nó chuyển đổi phương thức thành một hàm cho bạn.

Trong trường hợp val check, tuy nhiên, nó trông giống như kết quả cuộc gọi hàm được gán cho một biến. Trong thực tế, cả ba làm điều tương tự chính xác:

val check = dream 
val check = dream() 
val check = dream()() 

Nếu bạn muốn bật phương pháp này vào một chức năng, bạn đặt _ sau khi phương pháp ở vị trí của danh sách đối số (s). Do đó,

val check = dream() _ 

sẽ làm những gì bạn muốn.

5

Vâng, vấn đề là bạn đã hiểu sai. :-)

Dưới đây là một số sai lầm về khái niệm:

def dream()() = { 
    println("~Dream~"); 
    new Exception().printStackTrace() 
} 

Đây không phải là một chức năng một phần. Đây là phương thức được kết hợp với hai danh sách tham số trống trả về Unit.

val map = scala.collection.mutable.HashMap[String,()=>Unit]() 

Loại giá trị trong bản đồ này không phải là một phần chức năng, nhưng chức năng. Cụ thể, Function0[Unit]. Một chức năng một phần sẽ có loại PartialFunction[T, R].

map("dream") = dream()  // partial function 

gì xảy ra ở đây là Scala chuyển đổi phương pháp áp dụng một phần vào một hàm. Đây không phải là một nhiệm vụ đơn giản. Scala thực hiện chuyển đổi vì loại inferencer có thể đoán đúng loại.

val check = dream()   // unexpected invocation 

Ở đây không có loại được mong đợi để giúp trình inferencer loại. Tuy nhiên, danh sách tham số trống có thể được bỏ qua, vì vậy đây chỉ là một cuộc gọi phương thức.

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