Vui lòng xem mã followin, trong đó Extractor[A,B]
là một phần của khuôn khổ chung và mọi thứ khác nên được coi là "mã khách hàng" (tôi đã luộc nó xuống một chút và đổi tên Vì vậy, đừng bận tâm rằng Extractor
dường như không quá hữu ích).Thừa kế và (tự động?) Loại chuyển đổi
scala> abstract class Extractor[A,B] {
| def extract(d:A):B
| def stringRepr(d:A):String
| }
defined class Extractor
scala> sealed abstract class Value
defined class Value
scala> case class IntValue(i:Int) extends Value
defined class IntValue
scala> case class StringValue(s:String) extends Value
defined class StringValue
scala> case class Data(i:Int, s:String)
defined class Data
scala> sealed abstract class MyExtractor[Value] extends Extractor[Data, Value] {
| def stringRepr(d:Data) = extract(d) match {
| case IntValue(i) => i.toString
| case StringValue(s) => s
| }
| }
defined class MyExtractor
scala> class IntExtractor(name:String) extends MyExtractor[IntValue] {
| def extract(d:Data) = IntValue(d.i)
| }
defined class IntExtractor
scala> class StringExtractor(name:String) extends MyExtractor[StringValue] {
| def extract(d:Data) = StringValue(d.s)
| }
defined class StringExtractor
như vậy trong lời nói ngắn Extractor[A,B]
được sử dụng để trích xuất một số giá trị B
từ A
và làm một số việc khác mà không phải là đại diện trong mã chương trình này. Các lớp trừu tượng Value
và MyExtractor
được sử dụng vì lý do loại savety trong "mã khách hàng". Khi tôi cố gắng tạo ra một List
của MyExtractor
s, sau đây sẽ xảy ra:
scala> val l = List.empty[MyExtractor[Value]]
l: List[MyExtractor[Value]] = List()
scala> new IntExtractor("test1") :: l
res5: List[MyExtractor[_ >: IntValue <: Value]] = List([email protected])
cố gắng để chuyển đổi một IntExractor
đến một lớp cha
scala> new IntExtractor("test"):MyExtractor[Value]
<console>:24: error: type mismatch;
found : IntExtractor
required: MyExtractor[Value]
new IntExtractor("test"):MyExtractor[Value]
^
scala> new IntExtractor("test"):Extractor[Data,Value]
<console>:24: error: type mismatch;
found : IntExtractor
required: Extractor[Data,Value]
new IntExtractor("test"):Extractor[Data,Value]
Tôi biết rằng mọi thứ đều tốt, khi tôi xác định IntExtractor
như thế này
scala> class IntExtractor(name:String) extends MyExtractor[Value] {
| def extract(d:Data) = IntValue(d.i)
| }
defined class IntExtractor
scala> new IntExtractor("test"):Extractor[Data,Value]
res17: Extractor[Data,Value] = [email protected]
Nhưng tôi không hiểu, tại sao nó không hoạt động theo cách tôi thử nó ở trên. Tôi sẽ rất biết ơn vì bất kỳ trợ giúp hoặc gợi ý nào.
Theo nguyên tắc chung, việc sử dụng tên của các lớp thực tế cho các tham số kiểu là rất hữu ích. Ví dụ: trong 'lớp MyExtractor [Value]' giá trị 'là một tham số kiểu và không liên quan gì đến' giá trị lớp 'của bạn. Việc sử dụng tên này có xu hướng gây nhầm lẫn cho con người, mặc dù tất nhiên nó không bao giờ làm fazes trình biên dịch. –
'Extractor [A, B]' của bạn hoạt động giống như một 'A => B' (tức là một' Hàm1'). Lưu ý rằng 'Hàm1' là biến thể trong kiểu trả về của nó - nó được khai báo là' Hàm1 [-A, + B] ' –
@ Randall Schulz: Tôi không phải là 100% shure Tôi hiểu bạn đúng nhưng' Giá trị' trong 'lớp MyExtractor [Value] 'DOES tương ứng với' class Value'. Ví dụ tôi chỉ kiểm tra các lớp con của 'Value' trong' stringRepr (d: Value): String' – Agl