2014-12-04 78 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 

等等......