我有一个简单的类和一个使用apply方法重载的伴随对象:
case class A(val s: String,
val x: Int,
val y: Int,
val z: Int,
val foo: Int => Int,
val l: Option[List[String]])
object A {
def apply(s: String, x: Int, y: Int, z: Int, foo: Int => Int) =
new A(s, x, y, z, foo, None)
def apply(s: String, x: Int, y: Int, z: Int, foo: Int => Int, l: List[String]) =
new A(s, x, y, z, foo, Some(l))
}
我们还定义了一个函数:
def foo(x: Int): Int = x + 1
使用第一个构造函数:
scala> val a1 = A("a1", 1, 2, 3, foo)
a1: A = A(a1,1,2,3,$$Lambda$1842/2112068307@598e02f0,None)
然而,使用第二个不会:
val a2 = A("a1", 1, 2, 3, foo, List("b1", "b2"))
<console>:24: error: missing argument list for method foo
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `foo _` or `foo(_)` instead of `foo`.
val a2 = A("a1", 1, 2, 3, foo, List("b1", "b2"))
问题:我需要在foo _
示例中传递foo(_)
或a1
而不是foo的原因是什么?另外,我可以重新定义我的课程,以便只使用foo
吗?
答案 0 :(得分:2)
我无法解释这一点。我的第一个想法是它与类型擦除有关,正如slouc所说的那样,但后来我更仔细地查看了签名,即使在擦除之后它们都没有相同的类型签名:
案例类apply
:
String, Int, Int, Int, Function1, Option
伴随对象apply
1:
String, Int, Int, Int, Function1
伴随对象apply
2:
String, Int, Int, Int, Function1, List
所以,我不明白这是怎么回事。
尝试使其工作我已经注意到,如果将第二个apply
方法重命名为其他方法,它将正常工作:
scala> val a1 = A("a1", 1, 2, 3, foo)
a1: A = A(a1,1,2,3,$$Lambda$1286/1904652802@6b649efa,None)
scala> val a2 = A.apply2("a1", 1, 2, 3, foo, List("b1", "b2"))
a2: A = A(a1,1,2,3,$$Lambda$1287/866073173@2dd63e3,Some(List(b1, b2)))
或定义不在随播对象中的两个apply
方法:
object B {
def apply(s: String, x: Int, y: Int, z: Int, foo: Int => Int): A =
new A(s, x, y, z, foo, None)
def apply(s: String, x: Int, y: Int, z: Int, foo: Int => Int, l: List[String]): A =
new A(s, x, y, z, foo, Some(l))
}
REPL:
scala> val a1 = B("a1", 1, 2, 3, foo)
a1: A = A(a1,1,2,3,$$Lambda$1351/814507488@50fa5938,None)
scala> val a2 = B("a1", 1, 2, 3, foo, List("b1", "b2"))
a2: A = A(a1,1,2,3,$$Lambda$1352/613231852@5d77be8e,Some(List(b1, b2)))
第三种方法,如Robert Udah所述,将foo
定义为函数文字(x: Int) => x + 1
也解决了这个问题。但是,它不必是val
,也可以是def
:
def foo = (x: Int) => x + 1
答案 1 :(得分:0)
如果将foo
声明为函数val
scala> val foo = (x: Int) => x + 1
foo: Int => Int = <function1>
scala> val a1 = A("a1", 1, 2, 3, foo)
a1: A = A(a1,1,2,3,<function1>,None)
scala> val a2 = A("a1", 1, 2, 3, foo, List("b1", "b2"))
a2: A = A(a1,1,2,3,<function1>,Some(List(b1, b2)))
为什么def foo
适用于a1
我不确定,但它可能与case class A
期待函数而不是方法有关,因为这些显然是两个不同的东西在斯卡拉。