问题
I am trying to do:
MyObject.myMethod(_:MyType.myAttribute)
This fails with
type myAttribute is not a member of object MyObject
which is correct. The problem is that I want to call myMethod
on myAttribute
of _:MyType
, not ascribe MyType:myAttribute
to _
. Can I somehow group the type ascription _:MyType
? (_:MyType).myAttribute
returns type MyType => classOf(myAttribute)
, which is not what I want.
Edit: I changed the title and text of this post to no longer refer to this as the associativity of the dot, which I believe was not correct.
回答1:
Are you trying to create function (m: MyType) => MyObject.myMethod(m.myAttribute)
using underscore?
If so, the problem is that MyObject.myMethod((_:MyType).myAttribute)
means MyObject.myMethod((m:MyType) => m.myAttribute)
.
You can use infix notation:
MyObject myMethod (_:MyType).myAttribute
Proof it works:
scala> case class MyType(myAttribute: Int)
defined class MyType
scala> object MyObject {
| def myMethod(a: Int) = a.toString
| }
defined module MyObject
scala> MyObject myMethod (_:MyType).myAttribute
res0: MyType => java.lang.String = <function1>
scala> res0(MyType(1))
res1: java.lang.String = 1
scala> MyObject myMethod (MyType(1))
<console>:1: error: type mismatch;
found : MyType
required: Int
MyObject myMethod (_:MyType)
^
回答2:
I'm not sure whether this illustrates or answers your question, but it's true.
My guess is that you expected your a.b(_.i) to be an anon func after you add an ascription (to type the parameter).
But the subexpr foils you by there is no other expression of syntactic category Expr which is properly contained in e and which itself properly contains u.
(SLS 6.23)
Also, you can use scalac -Xprint:parser
to see how it's taken.
object Foo {
def m(k: Int) = 7 * k
}
class Bar {
val i = 5
val What = i
}
object Bar {
type What = Int
}
object Test extends App {
Foo.m(_:Bar.What)
// this is not anon func placeholder syntax...
//Foo.m((_:Bar).What) // _ is in a subexpr
//Foo.m(_.i)
// ...for this
val f = (x: Bar) => Foo.m(x.i)
// InfixExpr is ok
val g = Foo m (_: Bar).i
val b = new Bar
println(f(b))
println(g(b))
}
Contrast, to illustrate what is being restricted:
scala> val f: (Int,Int)=>Int = _+_
f: (Int, Int) => Int = <function2>
scala> val g: Int=>Int = if (_ > 0) 1 else 2
<console>:7: error: missing parameter type for expanded function ((x$1) => x$1.$greater(0))
回答3:
List(1,2,3).map((i: Int) => i * i)
EDIT
List(1,2,3).map((_: Int).unary_-)
EDIT 2
implicit class MyAttribute(i: Int) { def myMethod() = i * i }
List(1,2,3).map((_: Int).myMethod.unary_-)
Explanation
I used implicit class (Scala-2.10) to add myMethod on Int, after that unary "-" operation executed on result. You could add something like def wrap: MyAttribute
to MyAttribute
, and use it like (_: Int).wrap.method1.method2.method3.result.abs
, for example.
来源:https://stackoverflow.com/questions/13831313/force-grouping-of-ascription-on-underscore-in-scala