据报道,Dotty将具有类型参数的类与具有类型成员的类相关联,例如:
class C[T, U] { }
// <=>
class C {
type C$T
type C$U
}
Run Code Online (Sandbox Code Playgroud)
Dotty desugar多态方法如下例所示?
def m[T, U](x: T, u: U): T = x
// <=>
?
Run Code Online (Sandbox Code Playgroud) 我正在使用将标识符作为字符串传递的Java API。对我来说,使用键入符号似乎更好一些,所以我写了这样的代码:
object Helpers {
implicit def actionToString(action: Action): String =
action.getClass.getName.stripSuffix("$").replaceAll(".*\\$", "")
object Action{
def apply(name: String): Action = {
Class.forName("tutorial.HelloInput$Helpers$" + name).newInstance()
.asInstanceOf[Action]
}
}
sealed abstract class Action {
override def toString: String = actionToString(this)
}
final case class Rotate() extends Action
final case class Right() extends Action
final case class Left() extends Action
final case class Pause() extends Action
}
Run Code Online (Sandbox Code Playgroud)
这允许以自然的方式对字符串和操作进行“序列化”和“反序列化”,例如,我可以在模式上进行匹配Action(Pause)
,但Pause()
由于隐式转换,我也可以传递给期望字符串的Java库。
有没有更好的方法可以做到这一点,特别是在性能方面?这种方法有什么问题,以后可能会再次咬我吗?
我在阅读有关Dotty中Phantom类型的内容,并想知道它们是否可用于提高处理符号的性能(或者新的Enums将是更好的选择)。
我想实现通用和类型安全的域存储库。说我有
trait Repo[Value] {
def put(value: Value): Unit
}
case class IntRepo extends Repo[Int] {
override def put(value: Int): Unit = ???
}
case class StringRepo extends Repo[String] {
override def put(value: String): Unit = ???
}
case class DomainRepo(intRepo: IntRepo, stringRepo: StringRepo) {
def putAll[?](values: ?*): Unit // what type should be here?
}
Run Code Online (Sandbox Code Playgroud)
结果,我想要以下api:
domainRepo.putAll(1, 2, 3, "foo", "bar") //Should work
domainRepo.putAll(1, 2, true, "foo") // should not compile because of boolean value
Run Code Online (Sandbox Code Playgroud)
问题是如何实现这一目标?
因此,我只看到一种使其成为类型安全的方法。可以对任何类型的样式进行匹配
def putAll(values: Seq[Any]) …
Run Code Online (Sandbox Code Playgroud) 我想在包装函数中定义隐式值,并将其提供给内部函数使用,到目前为止,我设法通过从包装器传递隐式变量来做到这一点:
case class B()
trait Helper {
def withImplicit[A]()(block: => A): A = {
implicit val b: B = B()
block
}
}
class Test extends Helper {
def useImplicit()(implicit b: B): Unit = {...}
def test = {
withImplicit() { implicit b: B =>
useImplicit()
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否有可能避免implicit b: B =>
,并implicit val b: B = B()
提供给内部功能块?
在 scala 语言中,隐式解析通常在编译时完成,有时会抛出混淆的错误信息,此类错误的一个著名例子是当 shapeless Generic 抛出错误信息时,如:
error: could not find implicit value for parameter encoder: CsvEncoder[Foo]
Run Code Online (Sandbox Code Playgroud)
(详见https://books.underscore.io/shapeless-guide/shapeless-guide.html)
这个问题的一个解决方案是在运行时运行隐式解析算法(内部应该是图查询算法),这至少有两个好处:
调试工具可用于逐步重现解决过程,因此即使错误信息和文档不完整,也很容易发现错误。
在许多情况下,类型信息可能无法在编译时确定(例如,类型取决于控制流)。如果隐式转换不能延迟到运行时阶段,那么定义隐式转换的许多好处将无效。
所以我的问题是,Scala 2.x 或 Dotty 中是否存在此功能?还是在路线图上?
非常感谢您的意见。
我测试了以下结构类型的代码:
trait Data
object Main
{
def main(args: Array[String]): Unit =
{
val data = new Data {
val value: Int = 1
}
println(data.value)
}
}
Run Code Online (Sandbox Code Playgroud)
它在 Scala 2.13.2 中编译成功,但在 Dotty/Scala3 中失败。如何在 Dotty/Scala3 中使用结构类型?谢谢!
在Dotty 中给出以下内容:
object Domain {
final case class Create(name: String) extends BaseCreate[Create] {
override type Model = Domain
override def service[F[_]](client: KeystoneClient[F]): CrudService[F, Domain, Create] = client.domains
}
}
case class Domain(id: String)
class CrudService[F[_], Model, Create]
final class Domains[F[_]] extends CrudService[F, Domain, Domain.Create]
class KeystoneClient[F[_]] {
val domains = new Domains[F]
}
trait BaseCreate[Create <: BaseCreate[Create]] {
type Model
def service[F[_]](client: KeystoneClient[F]): CrudService[F, Model, Create]
}
Run Code Online (Sandbox Code Playgroud)
我想“简化” BaseCreate
,以便我可以这样实现Create
:
final case class Create(name: String) extends …
Run Code Online (Sandbox Code Playgroud) Scala 3 现在有一种改进的方式来定义 ADT。一种语法糖,消除了用通常的方式做这些事情的所有麻烦sealed trait
。
所以我会用一个例子来解释我的问题
enum Adt[+A]{
case Option1
case Option2
}
Run Code Online (Sandbox Code Playgroud)
在本例中Option1
和Option2
的类型为Adt[Nothing]
,因为类型参数A
是协变的。
如果枚举是逆变的,那么它们的类型就是Adt[Any]
。
但如果它是不变的呢?
考虑以下问题:
trait AA {
def children: List[AA]
}
trait BB {
def children: List[BB]
}
class CC extends AA, BB {
override def children: List[AA] & List[BB] = ???
}
Run Code Online (Sandbox Code Playgroud)
当我们覆盖children
in 时CC
,被覆盖的方法是顶级方法的合并实体。因此返回类型List[AA] & List[BB]
是有道理的。
我不明白的是,下面是如何编译的?
class DD extends AA, BB {
override def children: List[AA & BB] = ???
}
Run Code Online (Sandbox Code Playgroud)
List 是协变的,因此(这是证明的来源):
List[AA & BB] <: List[AA] & List[BB]
Run Code Online (Sandbox Code Playgroud)
DD
只能编译如果还 List[AA] & List[BB] <: List[AA & BB]
。这是真的吗?如果是这样,那么不是List[AA] & …