连接类型具有 Show 实例的多个值
Posted
技术标签:
【中文标题】连接类型具有 Show 实例的多个值【英文标题】:Concatenating several values where the type has a Show instance 【发布时间】:2021-07-27 04:55:06 【问题描述】:我想编写一个函数showAll
,它接受一个List
的值并生成一个String
,该String
是通过连接每个值的String
表示获得的,使用隐式范围内可用的Show
实例.
除了Show
实例的存在之外,列表元素的类型应该没有限制。
例如:
case class Person(name: String)
implicit val showPerson: Show[Person] = Show.by(_.name)
showAll(List(1, Person("Martin")))
应该输出:
1 Martin
在这种情况下,函数使用 Show[Int]
和 Show[Person]
实例。
函数的正确签名是什么?
谢谢。
【问题讨论】:
问题是 List 的类型是List[Any]
,没有 Show
没有简单的方法来拥有每个元素的 Show
。有很多技巧可以得到你想要的,从 magnet 模式,到创建一个自定义类,用它的 show 实例压缩每个元素,再到使用 Shapeless 来做自动压缩。
确实,这就是问题所在。我的第一个想法是添加一些常见的超类型 T,然后为 T 编写一个显示实例,但我想知道是否可以通过某种方式增强签名来解决它。无形看起来很有趣。
检查this (search for the section called "Bonus Round: How do we deal with collections?") - 如果你设法让它工作,请发布答案! :)
你坚持List
还是可变参数也适合你?喜欢showAll(1, person)
?
【参考方案1】:
这是我的示例代码,它可能会解决您的问题。 我已经创建了通用方法 show all,因为您需要显示 List 的元素。也是特定字段值的隐式方法。 MyClass 轨迹是标识符。如果 Myclass 不会被任何案例扩展,则不会打印特定类别的字段。
trait Myclass
case class Person(name: String) extends Myclass
case class Admin(name: String,age:Long) extends Myclass
def main(args: Array[String]): Unit =
showAll[Myclass](List(1, 2, Person("Martin"),Admin("Bob",30)))
implicit def showField: String = "name"
def showAll[T <: Myclass : ClassTag](listOfValues: List[Any]): Unit =
listOfValues.foreach data =>
if (data.isInstanceOf[T])
val myInstance= data.asInstanceOf[T]
val fld = myInstance.getClass.getDeclaredField(showField)
fld.setAccessible(true)
val value = fld.get(myInstance).asInstanceOf[String]
print(value + " ")
else
print(data + " ")
【讨论】:
以上是关于连接类型具有 Show 实例的多个值的主要内容,如果未能解决你的问题,请参考以下文章
为啥在具有多个连接的 WHERE 子句中,子查询比文字值执行得更好?