2012-05-09 46 views
5

Vì vậy, tôi muốn có một đặc tính chung như một tham số kiểu một lớp với một đối tượng đồng hành kế thừa từ một lớp cơ sở cụ thể và tham chiếu đến cả đối tượng đồng hành và chính lớp đó. Vì vậy,đặc điểm chung là một tham số kiểu

abstract class BaseModel[T] { 
    def all: Seq[T] 
} 

case class Customer(email: String, password: String) 

object Customer extends BaseModel[Customer] 

// This trait is my issue 
trait BaseCrud[T] { 
    def table[T](f: T => String): String = { 
    T.all.map(f _).mkString("") 
    } 
} 

object Controller with BaseCrud { 
    def foo = table(_.email) 
} 

Tôi đã có một số giải pháp cho đặc điểm đó gần hơn nhưng tôi chưng cất nó để bạn có thể thấy những gì tôi đang cố gắng làm.

Cảm ơn

CẬP NHẬT

Vì vậy, tôi đã đi với giải pháp từ Frank dưới đây, nhưng tôi đã quản lý để giải quyết câu đố ban đầu của tôi. Mặc dù, trong trường hợp này giải pháp là một chút xấu xí tôi sẽ bao gồm nó ở đây vì lợi ích đầy đủ.

abstract class BaseModel[T] { 
    def all: Seq[T] = Seq() 
} 

case class Customer(email: String, password: String) 

object Customer extends BaseModel[Customer] 

trait BaseCrud[T, U <: BaseModel[T]] { 
    def table(f: T => String)(implicit obj: U): String = { 
    obj.all.map(f(_)).mkString("") 
    } 
} 

object Controller extends BaseCrud[Customer, Customer.type] { 
    implicit val model = Customer 
    def foo = table(_.email) 
} 

Vì vậy, các thông số loại thay đổi để BaseCrud và tiềm ẩn đã được thêm vào BaseCrud.table và thực hiện tại Controller.model. Tôi cũng sửa tất cả lỗi chính tả của mình. Tôi thấy nó thú vị Customer.type dường như là loại đối tượng đồng hành.

Trả lời

1

Tôi nghĩ, bạn có thể sử dụng kiểu scala self trong đặc tính BaseCrud để chỉ định một lớp cần được trộn. Xem linked question để biết chi tiết.

trait BaseCrud[T] { 
    self: BaseModel[T] => 
    def table(f: T => String): String = 
    all.map(f).mkString("") 
} 

object Controller extends BaseModel[Customer] with BaseCrud[Customer]{ 
    def foo = table(_.email) 
} 
+0

Nhờ công trình nhưng tôi cần BaseModel tôi [T] trộn vào đối tượng khách hàng cho các bộ phận khác của mã này. Nhưng tôi đặt kỹ thuật này để sử dụng trong cùng một mã để truy cập Controller từ BaseCrud [T]. – gimo4000

6

Có một loạt các vấn đề trong mã của bạn .. chúng ta hãy giải quyết nó một sau khi khác:

  • def table[T](... lưu ý rằng T này ghi đè các tham số kiểu ban đầu cho phạm vi của phương pháp. Không phải những gì bạn muốn thực sự, vì vậy chỉ cần bỏ qua nó và làm cho điều này def table(...
  • object Controller with BaseCrud { chứa nhiều hai sai lầm:
    1. nó phải được extends không with. Sau này chỉ được sử dụng sau khi bạn đã mở rộng từ một số đặc tính/lớp cơ sở.
    2. BaseCrud đòi hỏi một tham số kiểu mà bạn phải chỉ rõ ở đây, vì vậy cái gì đó như BaseCrud[Customer]
  • và cuối cùng, để trả lời câu hỏi thực tế của bạn: Có sự khác biệt rất lớn giữa một loại tham số T và người bạn đồng hành đối tượng. Chúng vốn là những thứ khác nhau, vì vậy bạn không thể truy cập đối tượng đồng hành qua T.something. Thay vào đó, bạn cần phải cung cấp đối tượng đồng hành trong đặc điểm của bạn theo một cách khác, ví dụ như một trường trừu tượng.

Dưới đây là một phiên bản của những gì tôi tin rằng bạn muốn làm:

abstract class BaseModel[T] { 
    def all: Seq[T] 
} 

case class Customer(email: String, password: String) 

object Customer extends BaseModel[Customer] { 
    def all = List[Customer]() // have to define this 
} 

trait BaseCrud[T] { 
    val companion : BaseModel[T] 
    def table(f: T => String): String = { 
    companion.all.map(f).mkString("") 
    } 
} 

object Controller extends BaseCrud[Customer] { 
    val companion = Customer 
    def foo = table(_.email) 
} 
+0

Cảm ơn, điều đó làm việc hiệu quả. Xin lỗi về những sai lầm trong mã của tôi, hầu hết đã được gây ra trong việc tước bỏ trường hợp thử nghiệm.Tôi đã nhận ra rằng có một sự khác biệt giữa các đối tượng đồng hành và lớp của họ nhưng không thể tìm ra cách chuyển chúng thành các tham số kiểu (đó không phải là một giải pháp rất tốt). – gimo4000

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