2012-06-25 44 views
7

Tôi hiểu rằng các trường tham số (như ví dụ x trong ví dụ bên dưới) hoạt động như các trường thông thường; vì vậy bạn có thể tham khảo chúng trong các phương pháp:Các trường tham số và các tham số hàm của Scala

class Test(val x: Int) { // x is a parametric field 
    override def toString = "Test: " + x; 
} 

Tuy nhiên, nếu bạn thả từ khóa val, mã vẫn biên dịch (và tìm kiếm và .class đầu ra, x vẫn là một thành viên của lớp). Vì vậy, tôi tự hỏi, sự khác biệt giữa các trường tham số (tức là, val x: Int ở trên) và các đối số hàm tạo (x: Int) là gì?

(Với Java ở phía sau đầu của tôi, tôi đã có dự kiến ​​phạm vi của một nhà xây dựng như x-không bao gồm một phương pháp như toString.)

+0

Tôi tin rằng 'x' vẫn có đến một thành viên nếu nó được tham chiếu trong ít nhất 1 phương thức, bất kể nó có được bắt đầu bằng 'val' hay không. – adelbertc

Trả lời

9

Nếu không có từ khóa val, mã của bạn cũng tương tự như : class Test (private[this] val x: Int) { ... }. Do đó, x có sẵn trong cả lớp nhưng không phải từ bên ngoài.

Nó không được đề cập trong câu hỏi của bạn nhưng nó cũng có thể hữu ích: trong một case class công cụ sửa đổi mặc định là val. Do đó, case class Test(x: Int) {...} tương đương với case class (val x: Int) {...}.

+2

Tương đương trừ đi tất cả các thứ khác mà 'trường hợp lớp' có, tất nhiên. :-) –

+0

@ DanielC.Sobral Trên thực tế, tôi đã không chính xác nó bởi vì các lỗi đánh máy bạn sửa chữa không thực sự là một lỗi đánh máy. ;) – Nicolas

2

Thông số của hàm tạo có hiệu lực trở thành trường private[this] nhưng chỉ khi được tham chiếu trong ít nhất một phương pháp. Nếu không một trường không được tạo ra trong lớp.

Ví dụ:

class Foo(i: Int) { 
    println(i) 
} 

trở thành

$ javap -private Foo 
Compiled from "Foo.scala" 
public class Foo extends java.lang.Object implements scala.ScalaObject{ 
    public Foo(int); 
} 

Nhưng

class Bar(i: Int) { 
    def baz = println(i) 
} 

trở thành

$ javap -private Bar 
Compiled from "Bar.scala" 
public class Bar extends java.lang.Object implements scala.ScalaObject{ 
    private final int i; 
    public void baz(); 
    public Bar(int); 
} 
Các vấn đề liên quan