scala,我在使用pprint时丢失了类型信息

时间:2016-10-14 15:43:40

标签: scala

我希望def tuition(): tuition_cost=10000 increase=1.05 print('the cost for the year 10:', tuition_cost*(increase**10)) running_total = 0 for year in range(10): running_total += tuition_cost*(increase**year) print('the cost for 10 years:', running_total) for year in range(10,14,1): running_total += tuition_cost*(increase**year) print('the cost for 14 years:', running_total) tuition() toPrettyString1获得相同的结果,但似乎toPrettyString2会丢失类型信息,toPrettyString1不能删除字段并打印出来

为什么会这样,以及如何解决它?

pprint.tokenize

1 个答案:

答案 0 :(得分:1)

pprint库使用PPrint类型类来确定应如何打印特定类型的值。如果你有一个完全不受约束的类型T,你将得到一个PPrint实例,它只是在值上调用toString,这意味着你不会得到引号或好的转义pprint提供。

如果它对类型一无所知,这真的是所有pprint都可以合理地做的事情,甚至可以说这太多了 - 许多类型的基于类的库根本不提供这样的默认实例,即使存在可能的默认解释类型类操作应该做什么。

toPrettyString2按预期工作,因为您使用静态类型为tokenize的值调用EntryPPrint可为其提供更好的实例。如果您希望此行为具有泛型类型,则必须添加上下文绑定:

def toPrettyString3[T: pprint.PPrint](o: T) = pprint.tokenize(o).mkString

然后:

scala> println(toPrettyString3(entry))
Entry(1, "hello")

现在,您正在使用一些完全通用的T调用tokenize,但特别是使用T实例PPrint,并且当您调用toPrettyString3时使用Entry参数,库将为PPrint实例提供引号,转义等。

T: pprint.PPrint语法只是隐含参数的糖:

def toPrettyString3[T](o: T)(implicit pp: pprint.PPrint[T]) =
  pprint.tokenize(o)(pp).mkString

您没有定义隐式PPrint[Entry]实例,但是对于使用宏的案例类,库可以derive reasonable instances。如果由于某种原因你想要不同的行为,你也可以定义自己的实例,并且它会覆盖派生的实例。