Sử dụng loại lớp Numeric
trong đối tượng Interval
có thông số loại T
phải được đặt ở đâu đó trong phạm vi bao quanh của chúng. Interval
, là một giá trị không đổi duy nhất, không thể cung cấp liên kết đó.
Một giải pháp cho vấn đề cụ thể này sẽ được di chuyển các định nghĩa của union
và intersect
của bạn hoạt động vào Interval
lớp phương pháp dụ như bình thường, trong trường hợp đó họ sẽ chia sẻ những ràng buộc của T
và liên Numeric
dụ với phần còn lại của lớp,
case class Interval[T : Numeric](from: T, to: T) {
import Numeric.Implicits._
import Ordering.Implicits._
def mid: Double = (from.toDouble + to.toDouble)/2.0
def union(interval2: Interval[T]) =
Interval(this.from min interval2.from, this.to max interval2.to)
def intersect(interval2: Interval[T]) =
Interval(this.from max interval2.from, this.to min interval2.to)
}
Tuy nhiên, nếu bạn muốn giữ các định nghĩa của các hoạt động này tách biệt với Interval
lớp, một cách tiếp cận để giảm lượng soạn sẵn tiềm ẩn mà bạn cần phải đuổi throug h API của bạn là để xác định các lớp loại cấp cao hơn của riêng bạn về số [T]. Ví dụ,
// Type class supplying union and intersection operations for values
// of type Interval[T]
class IntervalOps[T : Numeric] {
import Ordering.Implicits._
def union(interval1: Interval[T], interval2: Interval[T]) =
Interval[T](interval1.from min interval2.from, interval1.to max interval2.to)
def intersect(interval1: Interval[T], interval2: Interval[T]) =
Interval[T](interval1.from max interval2.from, interval1.to min interval2.to)
}
implicit def mkIntervalOps[T : Numeric] = new IntervalOps[T]
mà sử dụng sẽ như thế nào,
def use[T](i1 : Interval[T], i2 : Interval[T])(implicit ops : IntervalOps[T]) = {
import ops._
val i3 = union(i1, i2)
val i4 = intersect(i1, i2)
(i3, i4)
}
Một lựa chọn thứ ba kết hợp hai, sử dụng một định nghĩa tiềm ẩn để làm phong phú thêm lớp ban đầu với các phương pháp bổ sung,
class IntervalOps[T : Numeric](interval1 : Interval[T]) {
import Ordering.Implicits._
def union(interval2: Interval[T]) =
Interval[T](interval1.from min interval2.from, interval1.to max interval2.to)
def intersect(interval2: Interval[T]) =
Interval[T](interval1.from max interval2.from, interval1.to min interval2.to)
}
implicit def enrichInterval[T : Numeric](interval1 : Interval[T]) =
new IntervalOps[T](interval1)
type Ops[T] = Interval[T] => IntervalOps[T]
Sau đó sử dụng,
def use[T](i1 : Interval[T], i2 : Interval[T])(implicit ops : Ops[T]) = {
val i3 = i1 union i2
val i4 = i1 intersect i2
(i3, i4)
}
Cảm ơn bạn. Đẹp ngắn gọn. Tôi chưa bao giờ thấy bối cảnh ràng buộc này. Người ta học những thứ như thế ở đâu? Tôi đọc một cuốn sách về Scala, nhưng tôi không nhớ lại giới hạn ngữ cảnh. –
Xem ví dụ [ngữ cảnh là gì "trong Scala?] (Http://stackoverflow.com/questions/2982276/what-is-a-context-bound-in-scala). – Jesper