2015-03-25 17 views
7

Xem mã,Tại sao loại trường hợp này có thể chứa nhiều tham số hơn so với trường hợp khai báo?

case class Wrapped[A](elem: A)(implicit ordering: Ordering[A]) 
    extends Ordered[Wrapped[A]] { 
    def compare(that: Wrapped[A]): Int = ordering.compare(this.elem, that.elem) 
    } 

tôi xác định một case class đây.

và sau đó gọi

Wrapped(1,2,2,4).

Tôi ngạc nhiên, ngay cả Wrapped(1,2,3,4,5) (bất kỳ số tham số nào) đều có thể hoạt động tốt mà không cần biên dịch lỗi.

+0

Ví dụ được bao bọc của bạn chỉ có một đối số duy nhất - một 'Tuple4 [Int, Int, Int, Int]'. – Lee

Trả lời

12

Nó được gọi là tự động tupling.

Trình biên dịch sẽ cố gắng bù đắp cho các đối số thừa bằng cách gói tất cả các đối số trong một bộ dữ liệu.

Wrapped(1,2,3,4) 

được tự động chuyển thành

Wrapped((1,2,3,4)) 

Bằng cách này, đây là một tính năng gây phiền nhiễu và gây ngạc nhiên và tôi thực sự hy vọng nó sẽ được dần dần bị phản đối. Trong khi đó bạn có hai tùy chọn biên dịch sẵn:

  • -Ywarn-adapted-args, rằng cảnh báo trong trường hợp autotupling
  • -Yno-adapted-args, cung cấp cho một lỗi trong các trường hợp tương tự

Ví dụ với cảnh báo:

scala -Ywarn-adapted-args 

scala> case class Foo[A](a: A) 

scala> Foo(1, 2) 
<console>:10: warning: Adapting argument list by creating a 2-tuple: this may not be what you want. 
     signature: Foo.apply[A](a: A): Foo[A] 
    given arguments: 1, 2 
after adaptation: Foo((1, 2): (Int, Int)) 
       Foo(1, 2) 
       ^
res1: Foo[(Int, Int)] = Foo((1,2)) 

Ví dụ có lỗi:

scala -Yno-adapted-args 

scala> case class Foo[A](a: A) 
defined class Foo 

scala> Foo(1, 2) 
<console>:10: warning: No automatic adaptation here: use explicit parentheses. 
     signature: Foo.apply[A](a: A): Foo[A] 
    given arguments: 1, 2 
after adaptation: Foo((1, 2): (Int, Int)) 
       Foo(1, 2) 
       ^
<console>:10: error: too many arguments for method apply: (a: (Int, Int))Foo[(Int, Int)] in object Foo 
       Foo(1, 2) 
       ^
+0

Đó thực sự là một "tính năng" khủng khiếp mà tôi không biết. – ziggystar

+0

"args được điều chỉnh" có đồng nghĩa với "autotupling" không? –

+0

Đó là chèn cộng đơn vị tự động, hiện đã không được dùng nữa –

1

Nhìn gần gũi hơn với mã của bạn:

Wrapped(1,2,3,4,5) 
res0: Wrapped[(Int, Int, Int, Int, Int)] = Wrapped((1,2,3,4,5)) 

Tham số được đầm vào Tuple đối tượng. Vì vậy, bạn có Wrapped[(Int, Int, Int, Int, Int)] thay vì mong muốn Wrapped[Int].

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