泛型类型的模式匹配
为什么我不能与 Node[T] 进行模式匹配?
object Visitor {
def inorder[T](root: Node[T]) : Unit = {
root match {
case End => return;
case Node[T] => {
if( root.left != null )
inorder( root.left )
println( root.toString );
inorder( root.right );
}
case _ => return;
}
}
}
更新:
该代码是99个scala问题
我收到此编译时错误:
BinaryTree.scala:25: '=>' expected but '[' found.
[error] case Node[T] => {
[error] ^
[error] one error found
第 25 行指向该行
case Node[T] => {
Why can't I pattern match against Node[T] ?
object Visitor {
def inorder[T](root: Node[T]) : Unit = {
root match {
case End => return;
case Node[T] => {
if( root.left != null )
inorder( root.left )
println( root.toString );
inorder( root.right );
}
case _ => return;
}
}
}
UPDATE:
The code is a verbatim copy from 99 scala problems
I'm getting this compile-time error:
BinaryTree.scala:25: '=>' expected but '[' found.
[error] case Node[T] => {
[error] ^
[error] one error found
Line 25 points to the line
case Node[T] => {
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在某些情况下,您可以绑定类型参数。绑定此类类型参数可用于对模式匹配子句的主体进行类型检查——由于擦除,这些绑定会被擦除,这意味着您无法在运行时区分它们(此类内容在 .NET CLR 中是可能的)。
不过,您的代码似乎没有使用该类型 - 人们需要查看 Node、End 的定义。实现您想要的简单方法可能是忽略 Node[T] 的类型参数是什么。下面是一个使用正确语法执行此操作的示例。
请注意,如果您想编写与某种类型(通用或非通用)匹配的模式,它的形式始终为
v : T
。另一方面,如果您匹配案例类,则模式的形状为C(p1...,pN)
。语言规范包含所有详细信息。我们还可以将其绑定到
_
,而不是将类型绑定到类型变量a
,以强调我们不使用此类型。You can bind the type parameter in some circumstances. Binding such type parameters can be used for typechecking the body of the pattern matching clause -- due to erasure, these bindings get erased and that means you cannot distinguish between them at runtime (such stuff is possible in the .NET CLR).
Your code does not seem to make use of the type though - one would need to see the definitions of Node, End. The simple way to achieve what you want is probably to just ignore what the type argument of Node[T] is. Below is an example that does this, with the correct syntax.
Note that if you want to write a pattern that matches on a type (generic or not), it always has the form
v : T
. If on the other hand, you match on case classes, then the pattern has the shapesC(p1...,pN)
. The language spec has all the details.Instead of binding the type to a type variable
a
, we could also bind it to_
, in order to stress that we do not make use of this type.好吧,我通过解释器运行你的代码,我认为它与类型擦除无关。可能只是一些语法错误。试试这个:
您需要指示将绑定到匹配的变量名称,例如
n:Node[T]
。这会向您发出有关类型擦除的警告,您可以使用n:Node[_]
删除该警告。编译器可以根据root
的类型推断出root.left
和root.right
的类型,因此类型擦除并不会真正起作用在这里玩...注意:我刚刚检查了规范,类型模式的语法是:
如果您提供来自编译器的实际错误消息以及 Node 和 End 的定义,这将会有所帮助,否则我们需要推断所有这些事物。
编辑:
假设您正在编译 http://aperiodic .net/phil/scala/s-99/tree.scala,您的代码中确实存在语法错误。使用
n:Node[_]
。然后你会得到一些类型错误。这对我有用:Well, I run your code through the interpreter and I think it has nothing to do with type erasure. May be just some syntax error. Try this:
You need to indicate the variable name that will be bound to the match, like
n:Node[T]
. That would give you a warning about type erasure, which you can remove by usingn:Node[_]
. The compiler can infer the type ofroot.left
androot.right
based on the type ofroot
so type erasure doesn't really come into play here...Note: I just checked the spec, the syntax for a type pattern is:
It would help if you provide the actual error message from the compiler, and the definition of Node and End as otherwise we need to infer all those things.
Edit:
Assuming you're compiling http://aperiodic.net/phil/scala/s-99/tree.scala, there is indeed a syntax error in your code. Use
n:Node[_]
. Then you'll get some type errors. Here is what works for me:为了在运行时匹配 Scala 中泛型的具体化类型,您需要使用 Manifests (qv) 编写代码的方式,将类型擦除。
In order to match the reified type at runtime for a generic in Scala, you need to use Manifests (q.v.) The way you wrote the code, the type is erased.
这种行为称为
类型擦除
。使用Manifests
,您可以制定解决方法。请参阅This behaviour is called
type erasure
. WithManifests
you can make a workaround. See this question for more information.