Scala不使用泛型参数
因此,如果可能的话,我想确保case match中的提取器将为它的别名提供正确的泛型类型Scala不使用泛型参数,scala,generics,pattern-matching,case-class,Scala,Generics,Pattern Matching,Case Class,因此,如果可能的话,我想确保case match中的提取器将为它的别名提供正确的泛型类型 trait MyT[A] case class MyC[A](t: MyT[A]) def foo: MyC[_] def go[A](t: MyT[A]): Option[MyC[A]] = foo match { case m@MyC(`t`) => Some(m.copy(t = t)) case _ => None } 这是可行的,但我宁愿不做m.copy(t=t)。基本
trait MyT[A]
case class MyC[A](t: MyT[A])
def foo: MyC[_]
def go[A](t: MyT[A]): Option[MyC[A]] = foo match {
case m@MyC(`t`) => Some(m.copy(t = t))
case _ => None
}
这是可行的,但我宁愿不做
m.copy(t=t)
。基本上,m@
将绑定到MyC[Any]
,但我希望它绑定到MyC[A]
。这是可能的,可能通过自定义不适用?您可以尝试显式地将类型参数a
归因于匹配的模式MyC
,并通过@取消选中消除警告:
trait MyT[A]
case class MyC[A](t: MyT[A])
def foo: MyC[_] = ???
def go[A](t: MyT[A]): Option[MyC[A]] = foo match {
case m: MyC[A @unchecked] if (m.t == t) => Some(m)
case _ => None
}
foo实际上返回MyC[\uz],不清楚我将如何在代码中更改它。我需要依赖foo。m.copy(t=t)
将只调用MyC(t)
,因此您可以编写它,而不需要m
(当然,这可能不适用于您的真实代码)。当然,重用m
会更好,但对我来说,这似乎是对copy
的严格改进。事实并非如此。如果我在MyC
中添加字段,我需要更改大小写匹配以及结果,而copy意味着我只需要更改大小写匹配。但是,只有当添加的字段与A
无关时。老实说,我比我无用的副本更糟糕,因为@unchecked
伤害了我。@allidoiswin它的伤害是否比编译器毫无怨言地尝试将m
与MyC(`t`)
模式匹配更大?或者编译器允许对甚至不需要相同类型的值调用=
?我不知道你对第一个关于m
vsMyC(`t`)
@allidoiswin的说法是什么意思。是的,=
使用等于。我只是看不出上面未选中的@unchecked
和类似def foobar[A](A:A,b:AnyRef):Option[A]={if(A==b)Some(A)else None}
。当使用=
时,对于本质上相同的“不安全”比较,它甚至不需要@未选中的
注释。@allidoiswin在前面的评论中,从a==b
可以得出结论b
属于的分支中的a
。同样,如果m.t==t
,您可以推断m.t
必须是MyT[A]
类型,因此m
必须是MyC[A]
类型。编译器没有看到这一点,因为它没有从m.t==t
这一事实中推断出任何有用的东西。不幸的是,这不是流敏感类型。。。