我再次与Scala闲聊,并希望这将是关于鸭子打字的基本问题,或者它可能真的与函数定义有关。让我解释一下:
给出以下代码:
package johnmcase.scala.oneoffs
object DuckTyping extends App {
def printIt(x:Int, y:Int) = println("Value with " + x + " = " + y);
// This method will accept ANY object that has a method named foo of type (Int) => Int
def duckTyped(duck: {def foo: (Int) => Int}) = {
List(1,2,3,4,5) foreach (i => printIt(i, duck.foo(i)))
}
println(new DoublerThatWontWork().foo(5))
println(new Doubler().foo(5))
println("DOUBLER:");
duckTyped(new Doubler());
println("Squarer:");
duckTyped(new Squarer());
println("AlwaysSeven:");
duckTyped(new AlwaysSeven());
println("DoublerThatWontWork :");
duckTyped(new DoublerThatWontWork ()); // COMPILER ERROR!!
}
class DoublerThatWontWork { // WHY??
def foo(x:Int) = x*2
}
class Doubler {
def foo = (x:Int) => x*2
}
class Squarer {
def foo = (x:Int) => x*x
}
class AlwaysSeven {
def foo = (x:Int) => 7
}
所以基本上我有一个方法“duckTyped”,它接受任何对象,只要该对象有一个名为“foo”的方法,它是一个Int => Int函数。
为什么类“DoublerThatWontWork”中foo的函数声明不满足函数duckTyped的参数类型?
答案 0 :(得分:7)
你的签名说有一个没有参数的方法foo,它返回一个从Int到Int的函数。你拥有的是一个带有Int参数和Int Result的方法。
你想要
duck: {def foo(i: Int) : Int}
(参数名称不必匹配)
答案 1 :(得分:4)
所以基本上我有一个接受任何对象的方法“duckTyped” 只要该对象具有名为“foo”的方法,即Int => Int 功能
实际上,这是不正确的。要使其正确,请将其更改为:
一个名为“foo”的无参数方法返回一个Int => Int功能。
没有方法“是”Int => Int
,因为这是一个类型,方法没有类型(即,它们不是对象),只需键入签名。
类型表示您是什么类型的对象。
类型签名表示如何调用方法及其返回的内容。
为了说清楚,以下两件事情并不相同:
def f(x: Int): Int = x * 2
def f: Int => Int = x => x * 2
第一种方法返回Int
,第二种方法返回Int => Int
。第一种方法有一个参数列表,一个Int
参数,而第二个方法没有参数列表。