2011-07-29 37 views
6

Tôi đang tìm cách xác định phương thức trả về kiểu T trong đó T = loại của lớp con.Loại trừu tượng Scala đại diện cho loại phân lớp

Tôi biết tôi có thể làm điều này bằng cách sử dụng các loại trừu tượng, nhưng không thích chi phí phải xác định lại T cho từng phân lớp.

Một số mẫu mã:

object Helper { 
    def help[A <: MyClass](cls: A): Option[A] = { cls.foo() map { _.asInstanceOf[A] } } 
} 

class MyClass { 
    type T <: MyClass 
    def foo(): Option[T] = Some(this.asInstanceOf[T]) 
} 

class ChildClass extends MyClass { 
    type T = ChildClass 
} 

Có thể là một tính năng ngôn ngữ mới đã làm cho dễ dàng hơn điều này? Hoặc tôi có thể sử dụng this.type theo một cách nào đó? Điều quan trọng với tôi là tôi có thể định nghĩa một lớp trợ giúp có thể gọi vào foo theo cách này.

Trả lời

3

Nếu bạn luôn quay trở lại this, thì bạn thực sự có thể có kiểu trả về this.type. Hay bạn đã thử nó chưa?

this.type đặc biệt hữu ích, ví dụ: khi bạn muốn chuỗi cuộc gọi đến cùng một đối tượng hoặc cung cấp bảo đảm tĩnh rằng bạn sẽ trả về cùng một đối tượng (chứ không phải bản sao). Ví dụ: Buffer s trong Scala có hoạt động nối thêm :+, trả về số Buffer[A]+=, trả về this.type. Các bản sao trước đó lặp lại chuỗi có thể thay đổi được; sau này đảm bảo rằng bạn cập nhật đối tượng gốc.

+1

Bất kỳ cơ hội bạn có thể chỉ cho tôi hướng tới một số cú pháp cụ thể mà sẽ làm việc cho rằng tôi cần phải viết Helper.help chính xác như là (với các tham số kiểu)? this.type không khớp với A? Ngoài ra, lưu ý rằng tôi cần phải trả về Option [this.type], và def foo: Option [this.type] = Một số (điều này) dường như không biên dịch. Cảm ơn bạn đã giúp đỡ! –

+1

@Pandora Singleton loại không bao giờ suy ra, bạn phải xác định rõ ràng: 'Some [this.type] (this)'. –

+0

Cảm ơn rất nhiều! Tôi đã chạy vào một trục trặc kể từ khi chức năng foo của tôi trong thực tế thực sự gọi ra phương pháp tĩnh của đối tượng khác -> theo dõi câu hỏi ở đây nếu bạn có hiểu biết :) http://stackoverflow.com/questions/6886182/scala-this- type-conformance-to-type-parameter-bounds-of-supertype –

2

Để theo dõi câu trả lời Jean-Phillippe, người đã viết của mình chính xác khi tôi đang viết tôi, đây là các mã:

trait SomeTrait { 
    def foo: this.type = this 
} 

class UsesTrait extends SomeTrait 

object Main { 
    def main(args: Array[String]) { 
    println((new UsesTrait).foo) // prints [email protected]<hash value> 
    } 
} 
+0

Tuyệt, điều này rất hữu ích. Điều này có mở rộng đến Option [this.type] không? def foo: Tùy chọn [this.type] = Một số (điều này) dường như không biên dịch. –

+0

Heh, cuối cùng tôi cũng đã kết thúc với điều này. Đây là một trong những tính năng ngôn ngữ không được ghi lại quan trọng nhất ... – lisak

2

tôi thấy thành ngữ sau đây hữu ích:

class MyClass[T] { 
    self: T => 
    def foo(): Option[T] = Some(this) 
} 

class ChildClass extends MyClass[ChildClass] 

new ChildClass().foo() 
//--> Option[ChildClass] = Some([email protected]) 
+0

Có, nhưng: • nó phải là một đặc tính nếu bạn muốn cho phép toàn bộ hệ thống phân cấp của các lớp, và • nó phải là biến thể trong ' T'. Nói chung, nhiều ràng buộc hơn một 'this.type' đơn giản, không? –

+0

@ Jean-Philippe Pellet: Vâng, có vẻ như. Tôi đang thiền cho dù nó có thể có lợi thế, quá, nhưng không tìm thấy một. – Landei

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