我希望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
答案 0 :(得分:1)
pprint库使用PPrint
类型类来确定应如何打印特定类型的值。如果你有一个完全不受约束的类型T
,你将得到一个PPrint
实例,它只是在值上调用toString
,这意味着你不会得到引号或好的转义pprint提供。
如果它对类型一无所知,这真的是所有pprint都可以合理地做的事情,甚至可以说这太多了 - 许多类型的基于类的库根本不提供这样的默认实例,即使存在可能的默认解释类型类操作应该做什么。
toPrettyString2
按预期工作,因为您使用静态类型为tokenize
的值调用Entry
,PPrint
可为其提供更好的实例。如果您希望此行为具有泛型类型,则必须添加上下文绑定:
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。如果由于某种原因你想要不同的行为,你也可以定义自己的实例,并且它会覆盖派生的实例。