2013-08-20 79 views
6

tôi đã viết một lớp mà chấp nhận một varargs như một tham số, và chỉ định mặc định của nó để người dùng thường có thể nhanh chóng nó mà không chỉ định một tham số:Tại sao không thể chỉ định giá trị mặc định của tham số Varala varargs?

class MyClass(values: Int* = 42) { } 

Tuy nhiên, trình biên dịch và REPL cho tôi các lỗi sau đây :

<console>:7: error: type mismatch; 
found : Int(42) 
required: Int* 
     class MyClass(values: Int* = 42) { } 
           ^
<console>:7: error: a parameter section with a `*'-parameter is not allowed to have default arguments 
     class MyClass(values: Int* = 42) { } 

là một workaround, tôi đã thử sau đây, nhưng nó đã không làm việc một trong hai: (. nó rất mơ hồ rõ ràng)

class MyClass(value: Int = 42, otherValues: Int*) { } 

Tôi tự hỏi tại sao nó không được phép có mặc định cho tham số varargs. Lý do kỹ thuật hoặc lý luận nằm dưới đây là gì? (Tôi đoán là chỉ định một varargs trống sẽ yêu cầu một số cú pháp đặc biệt hoặc thành ngữ, nhưng tôi không chắc chắn nếu đây là một lý do đủ.)

Trả lời

5

Suy nghĩ một chút về vấn đề này, tôi nghĩ rằng nó chỉ là một vấn đề không thêm quá nhiều phức tạp, giả sử bạn có

def f(a: A, xs: X* = Seq(x0, x1)) = ??? 

Bây giờ người gọi sử dụng như thế này: f(a).

Làm cách nào để biết người gọi có ý định vượt qua danh sách số không hoặc muốn kích hoạt các đối số mặc định bằng cách không cung cấp không? Trong ví dụ của bạn, bạn giả định rằng sự thay thế thứ hai là trường hợp duy nhất sẽ có và trình biên dịch cần cung cấp giá trị đối số mặc định. Nhưng một sản phẩm trống Seq() đã là một giá trị hoàn toàn hợp lệ do người gọi cung cấp. Tôi đoán người gọi có thể viết f(a, Seq(): _*) nhưng nó cồng kềnh.

+0

Tại sao 'def foo (kết quả: Int = 0, xs: String *) = ???' không được chấp nhận? Nó hoàn toàn khả thi cho trình biên dịch để nhận ra 'foo (0," không thể biên dịch ")' như là một công trình pháp lý. –

+0

@ om-nom-nom, không chắc tôi theo bạn.Tôi trả lời lý do tại sao chúng tôi có thể không muốn hỗ trợ 'def foo (kết quả: Int = 0, xs: String * = Seq (" một số "," mặc định ")) = ???'. – huynhjl

+0

yep, nhưng trình biên dịch đặt cùng giới hạn trong trường hợp của tôi (ít nhất là cho chúng ta cùng một lỗi biên dịch), vì vậy tôi đoán có thể có một số lý do khác hợp nhất hai trường hợp đó –

3

Varargs, không chỉ trong Scala, là một trừu tượng trên một danh sách các đối số , nếu tôi không nhầm, nó được chia nhỏ thành Seq, một danh sách các đối số. Xuất phát từ điều này, bạn mong đợi kết quả gì từ values: Int* = 42? Và sau đó, khi bạn gọi phương thức này, các đối số nên được chuyển vào phương thức này như thế nào?

+2

Nhưng bạn có thể làm ít nhất 'giá trị: Int * = (Mảng (42): Int *)' – Jatin

5

Từ scala đặc điểm kỹ thuật (Mục 4.6.2)

Không được phép để de fi ne bất kỳ đối số mặc định trong phần tham số với một tham số lặp đi lặp lại

Có lẽ một workaround sẽ giúp đỡ?

class MyClass(values: Int*) { 
    def this() = this(5) 
} 
+1

Nó không giải thích tại sao nó như vậy, chỉ cần mô tả từ chối như vậy. –

2

workaround khác là để làm cho Seq rõ ràng:

class MyClass(values: Seq[Int] = Seq(42)) { } 
+0

Vâng, đó là cách giải quyết mà tôi đã kết thúc. – trustin

2

Giá trị mặc định để varargs chỉ không có ý nghĩa, vì bạn không thể tìm ra bao nhiêu lý lẽ nên được thông qua. Đây không phải là một hạn chế của scala, đây là một giới hạn hợp lý.

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