'with' Scala 中关键字的大小写用法 类

'with' keyword usage in scala with case classes

我想如果这样的事情在 Scala 中有意义的话:

object CaseClassUnion extends App {
  case class HttpConfig(bindUrl: String, port: String)
  case class DbConfig(url: String, usr: String, pass: String)

  val combined: HttpConfig with DbConfig = ???
  
  //HttpConfig("0.0.0.0", "21") ++ DbConfig("localhost", "root", "root") 
  //would be nice to have something like that
}

至少这个编译...有没有办法,可能用宏魔法来实现两个 类 给定实例的联合? 在 zio 中,我相信有一些东西是相反的:

val live: ZLayer[ProfileConfiguration with Logging, Nothing, ApplicationConfiguration] =
ZLayer.fromServices[ProfileConfigurationModule.Service, Logger[String], Service] { (profileConfig, logger) =>  ???

我们将 ProfileConfiguration with Logging 转换为 ProfileConfigurationModule.Service, Logger[String] => Service

的函数

几件事。

当你有几个 traitwith 组合时,Scala 会进行特征线性化,将它们组合成一个具有线性层次结构的 class。但对于没有构造函数的 traits 来说是这样!

case class(这不是特征)不能用另一个 case class 扩展(根本),因为那样会破坏合同,例如:

case class A(a: Int)
case class B(a: Int, b: String) extends A(a)

A(1) == B(1, "") // because B is A and their respective fields match
B(1, "") != A(1) // because A is not B
B(1, "").hashCode != A(1).hashCode // A == B is true but hashCodes are different!

这意味着您甚至无法手动生成 case class 组合。您想“组合”它们,使用一些产品:元组,另一种情况 class,等等

如果你对ZIO好奇的话:

  • 使用特征
  • 将它们用作某种 type-level 技巧来表示一组无序的依赖项,其中类型推断将在您组合操作和一些巧妙的技巧以使用 [=17 从列表中删除特征时计算集合总和=] 从集合中删除依赖项
  • ZLayers 只是让这些恶作剧变得更容易

所以,如果你甚至传递了一些 A with B 你要么通过使用蛋糕模式自己组合它,要么你一个一个地传递依赖关系。 ZIO 开发人员可能永远不会遇到需要一些宏来组合多个 case classes (.provide(combineMagically(A, B, C, D, ...)) 的问题,因为他们可以一个接一个地传递每个依赖项的实现 (.provide(A).provide(B)) 并且下面的代码永远不需要这些类型的组合作为一个值——这只是一个 compile-time 技巧,可能永远不会转化为 A with B with C with D ....

类型的实际值的要求

TL;DR:您不能生成 2 个案例 classes 的组合; ZIO 使用复合类型作为某种 type-level 集来跟踪依赖关系,它实际上并不需要创建复合类型的值。