2017-04-20 46 views
0

地獄Scala專家 - 我需要你的幫助。 我想用類型參數編寫一些泛型函數,但是 類型參數沒有解析。即使簡單的內置類型如String也不能解決。我使用階2.12.1和IntelliJ 2017.1scala類型參數無法解析

我已附加以下

import java.lang.String 

trait hello_t 
{ 
    def hello_meth1:String 
    def hello_meth2[T]():T 
} 

class file_hello extends hello_t 
{ 
    // for example String here resolves to java.lang.String 
    val name:String = "test" 

    override def hello_meth1 = "hello from method 1" 

    //But type parameter "String" for hello_meth2 does not resolve - to java.lang.String 
    // And I get a compilation error see - below 
    override def hello_meth2[String] = "Hello from method 2" 

} 


object test extends App 
{ 
    val f1 = new file_hello 

    f1.hello_meth1 

    f1.hello_meth2 

} 

/* -- compilation error -- 
Error:(19, 39) type mismatch; 
found : java.lang.String("Hello from method 2") 
required: String 
override def hello_meth2[String] = "Hello from method 2"         ^
*/ 

回答

4

與一類參數的,抽象的方法的定義的代碼片段(如本情況下在trait)或不意味着這個方法是爲所有可能的類型定義的(除非你給這個類型一些限制,這在這裏不是問題)。

這意味着,當您實施hello_meth2[T](): T時,您應該爲任何類型提供類型爲T的值,而不僅僅是您決定的類型。

例如,在List[T]方法map[U](f: T => U): List[U]是創建List[U],任何類型U是,只要你有一個函數變換T值到U值的方法。

在你的情況,當你試圖實現hello_meth2file_hello,你給的類型參數(這是在trait稱爲T)這個名字String,但它仍然是一個類型參數,它適用於任何類型,而不僅僅是java.lang.String

你想要做什麼(如果我理解正確)可以用另一種方式解決:你想要的不是具有類型參數的方法,而是具有類型參數的特徵。事實上,你希望你的特質有一個方法,它的返回類型取決於特質的具體實現,所以這個類型應該是特性的一個參數。

trait hello_t[T] { 
    def hello_meth1:String 
    def hello_meth2():T 
} 

class file_hello extends hello_t[String] { 
    override def hello_meth1 = "hello from method 1" 
    override def hello_meth2() = "Hello from method 2" 
} 

或者,如果你不喜歡的類型參數,你可以有類型屬性(這是更面向對象):

trait hello_t { 
    type T 
    def hello_meth1:String 
    def hello_meth2():T 
} 

class file_hello extends hello_t { 
    type T = String 
    override def hello_meth1 = "hello from method 1" 
    override def hello_meth2() = "Hello from method 2" 
}