2011-01-13 25 views
5

Tôi muốn chuyển đổi hoàn toàn giữa đối tượng Scala XML Elem và một biểu diễn khác của một phần tử XML, trong phần tử dom4j Element của tôi. Tôi đã viết các chuyển đổi tiềm ẩn sau đây:Chuyển đổi ngầm định giữa các loại bộ sưu tập Scala

implicit def elemToElement(e: Elem): Element = ... do conversion here ... 
implicit def elementToElem(e: Element): Elem = ... do conversion here ... 

Cho đến nay rất tốt, công trình này.

Bây giờ tôi cũng cần bộ sưu tập các yếu tố đã nói để chuyển đổi cả hai cách. Trước tiên, tôi có cần viết các phương thức chuyển đổi bổ sung không? Mọi thứ dường như không hoạt động nếu tôi không làm.

Tôi cố gắng để viết như sau:

implicit def elemTToElementT(t: Traversable[Elem]) = t map (elemToElement(_)) 
implicit def elementTToElemT(t: Traversable[Element]) = t map (elementToElem(_)) 

này trông không quá lý tưởng vì nếu phương pháp chuyển đổi mất một traversable, sau đó nó cũng trả về một traversable. Nếu tôi vượt qua một danh sách, tôi cũng có được một Traversable ra. Vì vậy, tôi giả định việc chuyển đổi nên được parametrized bằng cách nào đó.

Vì vậy, cách tiêu chuẩn để viết những chuyển đổi này là gì để có thể nhận được thông tin chung nhất có thể?

Trả lời

1

Tôi nghĩ rằng điều này có thể mang lại quá nhiều. Đặc biệt là bạn chỉ có thể sử dụng phương pháp chuyển đổi trong bản đồ

val listOfElements = listOfElems map elemToElement(_) 

Tôi nghĩ rằng mức độ đồng nhất mà bạn đang chuẩn bị đang trở nên xáo trộn. Tôi sẽ tạo ra một lớp chuyển đổi và làm việc chỉ trong một trong những biểu diễn để giữ cho mọi thứ không bị lẫn lộn.

+0

Tại sao lại khó hiểu hơn khi có thể chuyển đổi tự động từ 'X' sang' Y' hơn từ 'Danh sách [X]' sang 'Danh sách [Y]'? Nó lấp đầy chính xác nhu cầu tương tự, cụ thể là bạn không thực sự quan tâm đến việc biểu diễn nào được sử dụng và bạn muốn trình biên dịch xử lý sự bận rộn cho bạn. –

+0

Phần lớn là vấn đề về phong cách và phương pháp hay nhất. Yêu cầu làm việc mà nhiều phép thuật đang yêu cầu rắc rối. Họ, theo quan điểm của tôi, một trong những BFGs của scala: hãy cẩn thận những gì bạn chỉ nó tại. – sblundy

+0

Tôi đồng ý với Rex: Tôi không đồng ý rằng điều đó gây nhầm lẫn. Ngược lại, tôi thậm chí đã hy vọng rằng việc xác định một chuyển đổi tiềm ẩn của một loại đã cho sẽ tự động chuyển đổi ngầm (tôi sẽ nói "monadic") cho loại đó hoạt động tốt. – ebruchez

2

Đây không phải là tầm thường để có được những gì bạn muốn Tôi nghĩ bạn sẽ phải đi sâu hơn một chút. Bài viết này giải thích rất nhiều về cách các bộ sưu tập scala hoạt động (và thú vị đọc nó là quá): http://www.artima.com/scalazine/articles/scala_collections_architecture.html

Về cơ bản bạn đang cố gắng thực hiện tương tự như List.map (...) (hoặc TraversableLike có triển khai thực hiện) và các phương thức tương tự .... chỉ với chuyển đổi tiềm ẩn ngoài ra.

Cập nhật:

tôi bắt đầu thử nghiệm một chút với điều này và đã viết một chuyển đổi dựa trên những gì TraversableLike.map (...) thực hiện. Tuy nhiên tôi phát hiện ra rằng nó làm việc ngay cả khi không có nó. Có vẻ như Scala hỗ trợ nó ra khỏi hộp (ít nhất là trên máy của tôi :-)):

case class Element(e: Elem) 
implicit def elemToElement(e: Elem): Element = Element(e) 
implicit def elementToElem(e: Element): Elem = e.e 

val a: List[Element] = List(<a/>, <b/>, <c/>) 
val b: List[Elem] = List(Element(<a/>), Element(<b/>), Element(<c/>)) 
val c: Set[Element] = Set(<a/>, <b/>, <c/>) 

Đây là những gì bạn đã làm sau?

+0

Cảm ơn con trỏ Tôi thực sự đã đi qua tài liệu đó một thời gian trước đây nhưng đã hy vọng cho một câu trả lời trực tiếp cho câu hỏi của tôi. #laziness – ebruchez

+0

Ồ, ví dụ của bạn hoạt động trong REPL!Bây giờ câu hỏi là tại sao nó không hoạt động trong bối cảnh mã của riêng tôi. Tôi nghi ngờ đó là vì tôi đang chuyển danh sách Scala [Elem] sang một phương thức yêu cầu java.util.List [Element]. Quy tắc "Một lần tại một thời điểm" khởi động, chỉ có một chuyển đổi tiềm ẩn được thực hiện. Tìm hiểu thêm về nó. – ebruchez

+0

Mmh, do đó không hoạt động khi gọi các hàm: 'def fa (p: List [Element]) {}; fa (b) '> lỗi: loại không phù hợp – ebruchez

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