Scala将函数作为参数传递给另一个函数

时间:2017-06-14 15:01:09

标签: scala function-parameter

抱歉这个烂摊子。我仍然在scala中找到自己的方式。重述所有问题是:

def func1(x: Double, y: Double) = {
  x+y
}

def func2(x: Double, y: Double) = {
  x-y
}

def calc(f: (Double, Double) => Double, z: Int) = {
  f(1,2) + z
}

//Sometimes I want to call
calc(func1(1,2), 3)

//Other times
calc(func2(1,2), 3)

我收到此错误:

<console>:52: error: type mismatch;
 found   : Double
 required: (Double, Double) => Double
              calc(func1(1,2), 3)
                        ^

调用calc()的正确方法是什么?

感谢

3 个答案:

答案 0 :(得分:1)

请注意,f()的参数,即12,都在calc()的正文中提供。

def calc(f: (Double, Double) => Double, z: Int) = {
  f(1,2) + z
}

因此,您无需为传入的函数指定任何参数。

calc(func1, 3)
calc(func2, 3)

答案 1 :(得分:0)

首先,你正在使用var(不想详细阅读this以获取更多信息),如果你的Map意味着在本地使用,那么这不是一个好习惯。你可以创建一个Mutable Map的类。

回到你的问题: 如果您希望函数按预期工作,那么您应该确保 doSomeComputation 函数返回 otherFunction 期望的值作为输入参数,类似这样

Sub Paste2()

Dim ws1     As Worksheet, ws2     As Worksheet
Dim aCell   As Range, rng As Range, cel As Range
Dim NextCol As Long, numOccur As Long

Set ws1 = ThisWorkbook.Sheets("RawData")
Set ws2 = ThisWorkbook.Sheets("Verbatim")
Set rng = ThisWorkbook.Sheets("RawData").Range("A1:ZZ1")
NextCol = 0

numOccur = Application.WorksheetFunction.CountIf(rng, Verb1)

Set aCell = rng.Cells(1, 1)
With ws1
    'Copy and Paste Verbatim
    For Each cel In rng
        NextCol = NextCol + 1
        Set aCell = .Range("A1:ZZ1").Find(What:=Verb1, LookIn:=xlValues, LookAt:=xlPart, _
            MatchCase:=False, SearchFormat:=False, SearchDirection:=xlNext, After:=aCell)
        Debug.Print Verb1 & " found in cell " & aCell.Address
        aCell.EntireColumn.Copy ws2.Cells(1, NextCol)
        If NextCol = numOccur Then Exit For
    Next cel
End With
End Sub

返回类型为(Map [String,List [String,Int]],String)

然而,对于你想要做的事情没有多大意义,我可以帮助你理解你是否可以清楚地提到你想要实现的目标。

答案 2 :(得分:0)

您需要传递函数签名f: (Map[String,List[(String, Double)]], String) => Double,而不仅仅是返回类型。以下是一个简单的例子:

var testMap: Map[String, List[(String, Double)]] = Map(
  "First" -> List(("a", 1.0), ("b", 2.0)),
  "Second" -> List(("c", 3.0), ("d", 4.0))
)
// testMap: Map[String,List[(String, Double)]] = Map(First -> List((a,1.0), (b,2.0)), Second -> List((c,3.0), (d,4.0)))

def doSomeComputation(m1: Map[String, List[(String, Double)]], name: String): Double = {
  m1.getOrElse(name, List[(String, Double)]()).map( x => x._2 ).max
}
// doSomeComputation: (m1: Map[String,List[(String, Double)]], name: String)Double

def doSomeOtherComputation(m1: Map[String, List[(String, Double)]], name: String): Double = {
  m1.getOrElse(name, List[(String, Double)]()).map( x => x._2 ).min
}
// doSomeOtherComputation: (m1: Map[String,List[(String, Double)]], name: String)Double

def otherFunction(f: (Map[String, List[(String, Double)]], String) => Double, otherName: String) = {
  f(testMap, "First") * otherName.length
}
// otherFunction: (f: (Map[String,List[(String, Double)]], String) => Double, otherName: String)Double

println(otherFunction(doSomeComputation, "computeOne"))
// 20.0

println(otherFunction(doSomeOtherComputation, "computeOne"))
// 10.0

根据您的使用情况,最好还将testMapname作为参数传递给otherFunction