Scala不使用泛型参数

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)。基本

因此,如果可能的话,我想确保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)
。基本上,
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
vs
MyC(`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
这一事实中推断出任何有用的东西。不幸的是,这不是流敏感类型。。。