3

我再次使用 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的参数类型?

4

2 回答 2

7

你的签名说有一个没有参数的方法 foo,它返回一个从 Int 到 Int 的函数。您所拥有的是具有 Int 参数和 Int Result 的方法。

你要

duck: {def foo(i: Int) : Int}

(参数名称不必匹配)

于 2012-04-27T17:49:26.177 回答
4

所以基本上我有一个方法“duckTyped”,只要该对象有一个名为“foo”的方法,它是一个 Int=>Int 函数,它就会接受任何对象。

实际上,这是不正确的。要使其正确,请将其更改为:

一个名为“foo”的无参数方法,它返回一个 Int => Int 函数。

没有方法“是” an Int => Int,因为那是一种类型,并且方法没有类型(即它们不是对象),只是类型签名。

类型表明你是什么类型的对象。

类型签名指示如何调用方法及其返回的内容。

为了清楚起见,下面的两件事是不一样的:

def f(x: Int): Int = x * 2
def f: Int => Int = x => x * 2

第一个方法返回一个Int,第二个方法返回一个Int => Int。第一种方法有一个参数列表,有一个Int参数,而第二种方法没有参数列表。

于 2012-04-27T20:32:01.107 回答