轉換

2013-10-29 70 views
3

說我有在Java中定義下面的類:轉換

public class A 
{ 
    public class B 
    { 
    } 

    public B[] someFunc() {...} 
} 

,我試圖如下訪問它在斯卡拉:

val array: Array[A#B] = a.someFunc() 

編譯器給我以下警告:

* type mismatch;找到:Array [aB] required:Array [A#B]注意:aB <:A#B,但類Array在類型T中不變。您可能希望研究通配符類型,例如`_ <:A#B *

我不知道我應該用來糾正這個錯誤的正確語法。我嘗試使用以下,但它不會編譯:

val array: Array[T <: A#B] = a.someFunc() 

但我發現走通過它傳遞給一個函數來克服這個問題:

def test[T <: A#B](array: Array[T]) = ... 
test(a.someFunc()) 

它編譯罰款。

我將如何實現正確的類型分配而不必定義此測試功能?

由於

回答

1

B內該類沒有標記static,這意味着,從階來看,它是不伴隨對象的成員(即,靜態成員) A#B,但它是實例化對象本身的成員a.B

所以,你應該只需要聲明你的價值是這樣的:

val array: Array[a.B] = a.someFunc() 

還是讓類型推斷做到這一點:

val array = a.someFunc() // typed as Array[a.B] 

編輯:如果你沒有a參考說謊通常你可以將a.B上傳到A#BArray是不變的,所以這是行不通的,但有一個詭計:將它包裝在協變的東西中。

val array: IndexedSeq[A#B] = a.someFunc() 

您可以使用一個像一個陣列,它實際上沒有任何轉換(它是一個WrappedArray),你可以在調用它toArray如果你真的想要得到的Array[A#B]

這只是避免做a.someFunc().asInstanceOf[Array[A#B]]的一招,但當然你可以直接做到這一點。

+0

該解決方案的問題是您需要對A對象的特定實例的引用。這並不總是可行的。假設我想定義一個類或一個函數來操作這種類型,當我沒有這樣的實例時。正如我在我原來的問題中所展示的,有一種方法可以通過定義一個函數來實現我想要的。我相信我們只是錯過了正確的語法來做到這一點,而不必定義這個函數。 – user79074

+0

你是對的,你需要一個'A'的實例。真正的問題是路徑依賴類型只是編譯器小說;在運行時,一切都是'A#B'。但是沒有直接的方式告訴編譯器「我知道我在做什麼,這是安全的」,當然除了演員。請參閱編輯。 – gourlaysama

+0

有一些斯卡拉領域肯定是值得的;這(非靜態內部類的實例的路徑依賴類型)似乎是其中之一。 –