所以我有一个简单的数字列表:
myList = List(13,24,10,35)
首先,我试着像这样过滤这个列表
myList.filter(_ => (_ % 5) == 0)
并且编译器抱怨因为它无法推断参数类型:
error: missing parameter type for expanded function ((x$2) => x$2.$percent(5))
myList.filter(_:Int => _ % 5 == 0)
现在编译器给了我这个:
identifier expected but integer literal found. someNumbers.filter(_:Int => _ % 5 == 0) ^
提前致谢,
解决方法
identifier expected but integer literal found. someNumbers.filter(_:Int => _ % 5 == 0) ^
是一个很棒的错误!好吧,从某种意义上说,人们并不喜欢它,但是你几乎写出了语法上正确的东西,并且与你的意图完全不同.首先,让我们看一下有效代码的重写:
someNumbers.map(_: Int => _ <:< Any)
现在,您看到它与您编写的内容之间只有两个不同之处(直到错误位置):%替换为<:,而5替换为Any(编译器需要 - 标识符而不是数字) . 你可以编译并运行上面的代码,它会返回一些东西,所以让我们试着把它分解.首先,考虑以下两个陈述:
someNumbers.map(_ + 1) someNumber.map(_) // does not compile
它们各自意味着略有不同,可以像这样重写:
someNumbers.map(x => x + 1) x => someNumbers.map(x)
第一个编译是因为,在声明x参数时,编译器知道预期的类型.第二个不编译,因为在编译器看到x时,它不知道如何使用它.当然,这只是因为编译器已经重写了代码,但事实就是如此.
这里重要的是,当你添加:Int时,编译器开始尝试编译你编写的第二种方式.
你打算写的东西不是有效的代码.例如:
someNumbers.map(x => x + 1) // valid code someNumbers.map((x: Int) => x + 1) // valid code someNumbers.map(x : Int => x + 1) // "invalid" code
更确切地说,第三个例子是“无效的”,因为编译器不知道类型的结束位置!要了解原因,请查看此声明:
val f: Int => Int = x => x
这里我们有=>出现两次,但每次都有不同的含义!第一种情况,Int => Int,是Function1 [Int,Int]的语法糖.换句话说,=>在Int => Int是该类型的一部分.
在第二种情况下,x => x(粗略地)代表新的Function1 [Int,Int] {def apply(x:Int)= x}. =>在此代码中表示存在匿名函数,并将其参数与其主体分开.
现在我们可以理解编译器如何解释someNumbers.filter(_:Int => _%5 == 0).像这样:
someNumbers.filter(_: Int => _ % 5 == 0) // gets rewritten as (x: Int => _ % 5 == 0) => someNumbers.filter(x)
意思是Int => _%5 == 0被认为是类型.我们已经看到了为什么=>不会阻止它,但错误只发生在5!这里和那里之间发生了什么?
首先,我将回到我的可编辑示例.它使用了一个不太清楚的Scala结构,并且经常看不到:中缀类型表示法.该示例可以重写如下:
someNumbers.map(_: Int => _ <:< Any) someNumbers.map(_: Int => <:<[_,Any])
换句话说,就像2 * 2代表2.*(2)一样,Int Map String代表Map [Int,String].这就解释了为什么编译器没有停在% – 它认为它代表一种类型 – 但它仍然留给我们_.
然而,在这一点上,_的含义,特别是在改写形式中,不应该看起来很神秘:它是一种存在主义类型!更具体地说,它是通配符存在类型.整个事情可以像这样重写:
(x: Function1[Int,<:<[t,Any] forSome { type t }]) => someNumbers.map(x)
或者,没有任何语法糖(但在实现*略有不同):
new Function1[Function1[Int,Any] forSome { type t }],List[<:<[q,Any] forSome { type q }]] { def apply(x) = someNumbers.map(x) }
现在,你不同意这几乎不能远离你想写的东西吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。