2014-12-04 32 views
0

我正在使用Python編寫的代碼移植到Scala。bencode Scala任何類型

此python代碼[0,{}]創建一個整數和字典的列表。

在這種情況下的字典將有字符串的鍵,但值可以是一個int或一個字符串。

我想在Scala中做類似的事情。我相信我將不得不這樣做:

List[Any] = (<int>, scala.collection.mutable.Map[String, Any](...)) 

我打算對此列表進行編碼,以便「任何」的基本類型很重要。如何更改類型以使列表可以被編碼?

+0

不是你的問題的答案,但我看到有人寫了Scala bencode庫,如[pyronicide](https://github.com/pyronicide/scala- bencode),並在[storrent]的層次結構中(https://github.com/danluu/storrent/blob /master/src/main/scala/Bencode.scala),或者[有趣的博客文章](http://covariantblabbering.blogspot.com/2014/05/the-beaty-of-parsing-combinators-and.html )。所以你可以在那裏找到一些好點子。 – wwkudu 2014-12-04 02:02:15

回答

1

在大多數情況下,在Scala中使用Any不是正確的做法。

由於您的問題是,映射值可以是IntString,而不是試圖用自己的普通型(任何),讓您自己的新類型層次來表示可能性:

sealed trait BData 
case class BInt(i: Int) extends BData 
case class BString(s: String) extends BData 

現在您的地圖將具有類型簽名Map[String, BData]

使用BData作爲「基礎類型」比使用Any更好,因爲它沒有歧義。它恰好有兩個子類;與Any相比,您的值可能是List[(Foo, Bar)],對於所有編譯器都知道。

0

我會帶dylan回答一點。
斯卡拉擁有強大的類型系統,你應該使用它。
當您使用任何與Java中的對象類似的東西時,就會丟失該類型。
你應該定義的類型,讓你的編譯器的工作:

sealed trait BData[T] { 
    val value: T 
} 
implicit class BInt(val value: Int) extends BData[Int] 
implicit class BString(val value: String) extends BData[String] 

的「隱性」的聲明,使編譯器的「轉換」的類型爲你,所以你可以使用它像這樣:

val bDataMap = scala.collection.mutable.Map[String, BData[_]]() 
val l = List((1, bDataMap)) 
l(0)._2 += ("myKey1" -> "Str") 
l(0)._2 += ("myKey2" -> 2) 

l(0)._2("myKey1").value 

等等......