2009-07-13 32 views
59

Trong Scala, một hàm tạo chính của lớp không có nội dung rõ ràng, nhưng được định nghĩa ngầm từ cơ thể lớp. Làm thế nào, sau đó, không một phân biệt giữa các lĩnh vực và giá trị địa phương (tức là giá trị địa phương để phương pháp constructor)?Làm thế nào để bạn xác định một var/val cục bộ trong hàm tạo chính trong Scala?

Ví dụ, lấy đoạn mã sau đây, một hình thức sửa đổi của một số mẫu mã từ "Lập trình trong Scala":

class R(n: Int, d: Int) { 
    private val g = myfunc 
    val x = n/g 
    val y = d/g 
} 

hiểu biết của tôi là điều này sẽ tạo ra một lớp học với ba lĩnh vực: a private " g "và công khai" x "và" y ". Tuy nhiên, giá trị g chỉ được sử dụng để tính toán các trường x và y, và không có ý nghĩa ngoài phạm vi của hàm tạo.

Vì vậy, trong ví dụ này (thừa nhận nhân tạo), làm cách nào để bạn xác định giá trị cục bộ cho hàm tạo này?

+0

Đăng trong trường hợp những người khác có câu hỏi tương tự như tôi và đến đây trước tiên như tôi đã làm. Nếu bạn đang cố gắng thực hiện cùng khái niệm này nhưng đối với _constructors_, hãy sử dụng câu trả lời cho câu hỏi của tôi: https://stackoverflow.com/questions/46455835/how-to-define-val-inside-class-constructor-in-scala –

Trả lời

37

Ví dụ:

class R(n: Int, d: Int) { 
    val (x, y) = { 
    val g = myfunc 
    (n/g, d/g) 
    } 
} 
+0

Ah, thật đơn giản. Tôi vẫn nhận được trực giác của tôi xung quanh khái niệm chức năng. – skaffman

+47

Điều này sẽ thực sự thêm một trường Tuple2 ẩn vào lớp của bạn. –

+2

Điều này có thể quan trọng. Cảm ơn bạn đã bình luận, Jorge. –

16

Có một số cách để thực hiện điều đó. Bạn có thể khai báo các biến tạm thời như vậy trong các định nghĩa riêng, được sử dụng trong suốt thời gian xây dựng. Bạn có thể sử dụng các biến tạm thời bên trong các khối trả về các biểu thức (như trong câu trả lời của Alaz). Hoặc, cuối cùng, bạn có thể sử dụng các biến đó bên trong các hàm tạo thay thế.

Theo cách tương tự như các nhà thầu thay thế, bạn cũng có thể xác định chúng bên trong phương thức "áp dụng" của đối tượng đồng hành.

Điều bạn không thể làm là khai báo trường là "tạm thời".

Cũng lưu ý rằng mọi tham số nhận được bởi hàm tạo chính cũng là trường. Nếu bạn không muốn các tham số đó trở thành các trường và không muốn để lộ các trường thực tế trong một hàm tạo, thì giải pháp thông thường là làm cho hàm tạo chính riêng, với các trường thực tế và sử dụng một hàm tạo thay thế hoặc một đối tượng của đối tượng áp dụng() làm hàm tạo "chính" có hiệu quả.

+0

Cảm ơn bạn đã làm rõ. – skaffman

6

Một số cuộc thảo luận về chủ đề này, trong đó có ý kiến ​​Martin Odersky, là here

+0

Đó là ví dụ chính xác từ cuốn sách đã kích hoạt câu hỏi của tôi :) Tôi cho rằng điều đó có nghĩa là tôi đã chú ý ... – skaffman

+0

Chủ đề bị xóa. – ziggystar

+5

Liên kết thay thế: http://www.scala-lang.org/node/1198#comment-3430 – robinst

11

Một tùy chọn khác chúng tôi có là làm cho các nhà xây dựng đối tượng chính cá nhân và sử dụng một bạn đồng hành của đối tượng áp dụng phương pháp như một người thợ xây. Nếu chúng ta áp dụng (chơi chữ không có ý định) phương pháp này để ví dụ của bạn, nó sẽ giống như thế này:

class R private (val x: Int, val y: Int); 

object R { 
    def apply(n: Int, d: Int): R = { 
    val g = myfunc; 
    new R(n/g, d/g); 
    } 
} 

Để tạo một thể hiện R thay vì:

val r = new R(1, 2); 

viết:

val r = R(1, 2); 

Đây là một chút tiết, nhưng nó có thể tồi tệ hơn, tôi nghĩ :). Hãy hy vọng rằng các vals riêng tư này sẽ được coi là các biến tạm thời trong các phiên bản tương lai của Scala. Bản thân Martin gợi ý điều đó.

+1

Tối ưu hóa chưa được triển khai như Scala 2.9.0.RC1. – robinst

+0

robinst, ngay cả trong Scala 2.10.2 – MyTitle

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