2012-06-22 34 views
6

Cho phép tôi có một lớp tiện ích được gọi là MathUtil.Scala Số init với hằng số 0

và có vẻ như thế này.

abstract class MathUtil(T:Numeric){ 
    def nextNumber(value:T) 
    def result():T 
} 

Cho phép tôi phân lớp nó cách

class SumUtil[T:Numeric] extends MathUtil[T]{ 
    private var sum:T = 0 
    override def nextNumber(value:T){ 
    sum = sum + value 
    } 
    override def result():T = sum 
} 

này, tôi có một vấn đề với tuyên bố

private var sum:T = 0 

Bây giờ, tôi phải khởi tạo để tổng hợp để 0. Tôi sẽ đoán bất kỳ số để có một cách để đại diện cho 0. Im khá mới để scala. Làm cách nào để giải quyết vấn đề này?

+0

Cảm ơn mọi người vì câu trả lời. Tôi có một câu hỏi tiếp theo. Cho phép nói rằng tôi có một lớp học có thành viên overrideable MathUtils loại. – questionersam

Trả lời

11

Các Numeric type class instance có một phương pháp zero mà những gì bạn muốn:

class SumUtil[T: Numeric] extends MathUtil[T] { 
    private var sum: T = implicitly[Numeric[T]].zero 
    override def nextNumber(value: T) { 
    sum = implicitly[Numeric[T]].plus(sum, value) 
    } 
    override def result(): T = sum 
} 

Lưu ý rằng bạn cũng cần sơ thẩm đối với phương pháp plus, trừ khi bạn nhập Numeric.Implicits._, trong trường hợp này bạn có thể sử dụng +. Bạn cũng có thể làm sạch mã lên một chút bằng cách không sử dụng bối cảnh bị ràng buộc cú pháp trong trường hợp này:

class SumUtil[T](implicit ev: Numeric[T]) extends MathUtil[T] { 
    import Numeric.Implicits._ 
    private var sum: T = ev.zero 
    override def nextNumber(value: T) { 
    sum = sum + value 
    } 
    override def result(): T = sum 
} 

Đây chính là tương đương: phiên bản bối cảnh bị ràng buộc là đường chỉ là cú pháp cho tranh luận ngầm này, nhưng nếu bạn cần sử dụng đối số đó một cách rõ ràng (như bạn làm ở đây, cho zero) của nó, tôi thấy nó sạch hơn để viết phiên bản desugared.

+0

Hey Travis! Rất vui khi thấy bạn đăng bài ở đây (đây là Ben từ Austin). Thật không may điều này là số, IMO, chỉ hoàn toàn fugly. Hóa ra nó cũng chậm như địa ngục. IMO toàn bộ cơ chế ngầm Scala là clunky, giòn và khó hiểu và bạn vẫn cần rác khác như @specialized, mà cũng là chủ yếu bị tấn công. Tôi nghĩ rằng công cụ này sẽ được thể hiện tốt hơn bằng cách sử dụng C++ - phong cách lớp chuyên môn, mà sẽ * chỉ * * làm việc * theo cách mọi người mong đợi, về cơ bản bằng cách sao chép thực hiện với s/int/double/hoặc bất cứ điều gì. –

+0

@UrbanVagabond: Xin chào, Ben! Tôi đồng ý rằng 'Numeric' là một mớ hỗn độn, và tôi không thể nhớ lần cuối tôi sử dụng nó trong mã của riêng mình, nhưng cá nhân tôi không nghĩ rằng vấn đề là cách Scala thực hiện các lớp kiểu (mà tôi đã thực sự phát triển thích). –

0

Tôi nghĩ rằng cần phải có một chút làm rõ chính xác những gì bạn đang cố gắng hoàn thành. Từ các tài liệu Scala, kiểu số là chính nó. Cảm giác của tôi ở đây là những gì bạn thực sự muốn là mô tả một trừu tượng MathUtil xử lý bất kỳ số [T] nào chứ không phải là các lớp con của số [_] mà là mã của bạn hiện đang mô tả. Đây là việc thực hiện chính xác dựa trên giả định đó.

//Define a MathUtil that works on any T 
abstract class MathUtil[T] { 
    def nextNumber(value: T) 
    def result(): T 
} 

//Define a SumUtil that works on any T that has an available Numeric 
//Will search implicit scope, but also allows you to provide an 
//implementation if desired. 
class SumUtil[T](implicit n: Numeric[T]) extends MathUtil[T] { 
    //Use the Numeric to generate the zero correctly. 
    private var sum: T = n.zero 
    //Use the Numeric to correctly add the sum and value 
    override def nextNumber(value: T) = sum = n.plus(sum, value) 
    override def result(): T = sum 
} 

//Test that it works. 
val a = new SumUtil[Int] 
val b = List(1,2,3) 

b map a.nextNumber //Quick and dirty test... returns a meaningless list 
println(a.result) //Does indeed print 6 

Nếu ở trên không làm những gì bạn muốn, vui lòng làm rõ câu hỏi của bạn.

+0

Bạn không đúng ... '[T: Numeric]' là một ngữ cảnh bị ràng buộc và sẽ mở rộng thành '[T] (ngầm định n: Numeric [T])', vì vậy mã của bạn gần như giống như OP trừ cho 'n.zero'. – drexin