0

如果我有一个 Scala 特征,其中定义了两个函数,一个仅使用签名定义,另一个使用def foo : Int => String参数和返回类型声明的函数,def bar(myInt : Int): String那么我会为这些方法获得不同的行为。

import org.scalamock.scalatest.MockFactory
import org.scalatest.{Matchers, WordSpec}

class DefTest {

  trait DefTrait {
    def foo : Int => String
    def bar(myInt: Int) : String
  }

  class DefTest extends WordSpec with Matchers with MockFactory {
    val defStub = stub[DefTrait]

    defStub.bar _ when * returns "Works"
    defStub.foo _ when * return "nope"

  }
}

仅签名失败

IntellJ 说有Too many arguments for method whenexpected: FunctionAdapter0[Boolean], actual: MatchAny

SBT 说:

type mismatch;
[error]  found   : org.scalamock.matchers.MatchAny
[error]  required: org.scalamock.function.FunctionAdapter0[Boolean]
[error]     defStub.foo _ when * returns "nope"
[error]                        ^

这让我想知道:

  1. 这两种类型的函数声明有什么区别?我认为它们是等价的,直到现在我似乎都可以互换使用它们。
  2. 是否可以使用foo: Int => String带有defStub.foo _ when 42 return "yay"语法的签名函数定义?
4

1 回答 1

4

1. 这两种函数声明有什么区别?

因为def foo : Int => String它返回一个没有接受参数的高阶函数:

scala> :kind -v foo
scala.Function1's kind is F[-A1,+A2]
* -(-)-> * -(+)-> *
This is a type constructor: a 1st-order-kinded type.

当你调用时foo(2),它等于foo.apply(2)apply方法用于函数执行。

对于def bar(myInt: Int) : String,它是一种接受Int参数的方法。

2.是否可以使用签名函数定义 foo: Int => String 和 defStub.foo _ when 42 return "yay" 语法?

因为def foo : Int => String它不接受参数,所以你应该使用when()它,它的返回类型是Int => String,所以你应该为这个方法提供returns一个高阶函数。喜欢:

defStub.foo _ when() returns((i: Int) => "nope")
于 2017-06-28T08:12:04.060 回答