2011-05-14 160 views
3

我想寫一個通用方法來獲取String或Int的位置x上的元素。 現在我的問題是,我如何強制Scala將T轉換爲Int或調用一個Int特定的方法。scala類型匹配

下面是代碼:

def key[T](elm:T,pos:Int) = elm match{ 
    case x:Int => { 
    def digit(number:Int, pos:Int):Int = { 
     if(pos == 0) number % 10 
     else digit(number/10, pos-1) 
    } 
    digit(elm.toInt,(elm.toInt).length-pos-1) 
    } 
    case x:String => (elm.toString).charAt(pos) 
} 

謝謝!

回答

0
def key[T](elm:T,pos:Int) = elm match { 
    case x:Int => { 
    def digit(number:Int, pos:Int):Int = { 
     if(pos == 0) number % 10 
     else digit(number/10, pos-1) 
     } 
    digit(x,x.length-pos-1) 
    } 
    case x:String => x.charAt(pos) 
} 
+0

同樣的問題:值的長度不是int 位(X,x.length-POS-1) – xyz 2011-05-14 21:00:33

+0

咄的成員。 '長度'不是Int的一種方法,但你可以取對數(以10爲底)來得到它。 – 2011-05-14 21:14:11

+0

Int沒有長度方法。 – 2011-05-14 21:15:04

2
def key[T](elm:T,pos:Int) = elm match { 
    case x:Int => x.toString.charAt(pos) 
    case s:String => s.charAt(pos) 
} 

利用溶液觀點:

+0

啊很酷這是工作:)但我的問題仍然存在。我該如何強迫scala認爲elm是Type的例如Int,以便我可以調用elm.length方法? – xyz 2011-05-14 21:05:24

+0

第二種解決方案也可以使用x.length而不是x.charAt,以防您想要遞歸查找答案。 – pedrofurla 2011-05-14 21:13:06

+2

x *是* elm,但被視爲一個Int。 – 2011-05-14 21:14:15

1

我會說,你的問題是,你有兩種類型上你喜歡的工作,一個int和一個字符串,你想要在該輸入上執行鍵方法,但不指定,您想返回的內容。

我對Int的第一個想法是返回一個Int。 。的toString()的charAt(N)似乎是一種欺騙,但也許作弊是好的,讓我們開始作弊:

def cheat (a: Any, n: Int) = a.toString().charAt (n) 
cheat (2345, 2) 
// res414: Char = 4 
cheat ("foobar", 2) 
// res415: Char = o 

這是很好的和容易的,不是嗎?但是,如果您希望爲Int輸入返回一個Int,並且爲String的輸入返回一個String?字符似乎是一個String類型的輸入更自然,一個字節就足以從0-9返回一個數字,但我們有一個簡單的類型依賴,如果我們返回一個T代表一個T.

我不相信我的解決方案,但我不相信作弊,第一種解決方案只是一種更復雜的作弊方式,不是嗎?

class Atti [T] (val fun: (Int => T)) { 
    def at (n: Int): T = fun (n) 
} 

我定義的姿態級,這對於一個T型需要一個函數,它接受一個int,並返回一個T,如果你對這個類調用at,它會調用該函數。

現在我們定義一個函數的iget,從一個Int獲得位於n的數字,我們用兩個參數列表,...

def iGet (i: Int) (n: Int) : Int = { 
    if (n == 0) i % 10 
    else iGet (i/10)(n - 1) } 

...傳遞詮釋,在其上操作,急切地,以限定一個局部定義的函數:

val iAt = new Atti[Int] (iGet (2345) _) 
(0 to 3).map (iAt.at (_)) 
// res412: scala.collection.immutable.IndexedSeq[Int] = Vector(5, 4, 3, 2) 

模擬功能的字符串,並聲明SAT的:

def sGet (s: String) (n: Int) : String = "" + s.charAt (n) 

val sAt = new Atti[String] (sGet ("foobar") _) 
(0 to 3).map (sAt.at (_)) 
// res413: scala.collection.immutable.IndexedSeq[String] = Vector(f, o, o, b) 

我想你會發現字符串是從左到右評估的,而Int是從右到左評估的,就像在你對問題的介紹中一樣。

我不喜歡自己是,那個有效載荷'foobar'不再是一個字符串,並且2345以某種方式隱藏在iAt對象中。

並且需要爲每個字符串指定用於字符串的函數 - 這爲您提供了比您要求的更大的靈活性,併爲每個實例提供了更多的工作。

我試圖建立一個特點,它混合轉換成int或字符串,但沒有成功:

trait Key [T] { def at (n: Int): T } 
val s : String with Key[String] = "Foobar" { def at (n: Int) : String = "" + s.charAt (n) } 
<console>:7: error: type mismatch; 
found : Unit 
required: Int 
     val s : String with Key[String] = "Foobar" { def at (n: Int) : String = "" + s.charAt (n) } 
                           ^
0

我怎麼能強迫斯卡拉至T轉換爲 詮釋

你不能。那麼,你可以進行一些隱含的檢查,但這比你必須做的更難。代替使用elm的,使用x

def key[T](elm:T,pos:Int) = elm match{ 
    case x:Int => { 
    def digit(number:Int, pos:Int):Int = { 
     if(pos == 0) number % 10 
     else digit(number/10, pos-1) 
    } 
    digit(x,x.toString.length-pos-1) 
    } 
    case x:String => x.charAt(pos) 
}