2012-04-17 86 views
0

使用其参考ARGS函数考虑下面的代码:调用与斯卡拉

object HelloIntelliScala { 
    def main(args : Array[String]) = { 
    println(callAnyFunc(funcWithNoArgs)) 

    val l = callAnyFuncWithArgs("bingo") (funcWithArgs) 
    println(l) 

    val l2 = callAnyFuncWithArgs(21) (funcWithArgs2) 
    println(l2) 

    } 

    type noArgCallBack =() => Any 

    def funcWithArgs(inp : String) : Any = { 
    println("Func with arg called, arg value is: " + inp) 
    "Hello " + inp + "!" 
    } 

    def funcWithArgs2(inp : Int) : Any = { 
    println("Func with arg called, arg value is: " + inp) 
    "Hello, integer " + inp + "!" 
    } 

    //how do i call this function? 
    def funcWithArgs3(inp : Int, name : String) : Any = { 
    println("Func with 2 args called, arg values are: " + (inp, name)) 
    "Hello, multiple args " + (inp, name) + "!" 
    } 

    def funcWithNoArgs() : Any = { 
    println("Function with no args was called!") 
    "Hello NO_ARGS" 
    } 

    def callAnyFunc(callback : noArgCallBack) : Any = { 
    callback(); 
    } 

    def callAnyFuncWithArgs[A, B](arg : A)(f : A => B) : Any = { 
    f(arg); //how do I pass variable args here 
    } 
} 

我需要一个通用的方法来调用带参数的任何功能,就像一个不带参数。请注意,要传递的参数列表可以是可变的,我们不知道编译时的参数类型。此外,我确实需要Any返回类型,因为我需要将此值用于后期处理。有没有办法做到这一点?

+0

为了澄清,我需要使用泛型调用机制调用多个这样的函数。 – 2012-04-17 08:17:01

+0

[loan pattern](https://wiki.scala-lang.org/display/SYGN/Loan)有帮助,但我仍然无法弄清楚如何使它适用于变量arg列表。 – 2012-04-17 08:43:46

+0

已更新代码以包含贷款模式,以允许我调用只接受一个参数的函数,如何将它扩展为变量参数列表? – 2012-04-17 08:48:50

回答

3

斯卡拉不会抽象方法arity。或者换句话说,如果不为每个团体编写模板,就没有办法做到这一点。

幸运的是,Miles Sabin用Shapeless写下了所有样板文字。

+0

谢谢,我认为这可能只适合该法案;让我运行一些测试用例,我会回来的。 – 2012-04-17 15:59:36

+0

我暂时接受你的回答,虽然我无法深入潜入无形,它看起来会满足我的需求。感谢您的帮助。 – 2012-07-15 16:25:43

1

这可能可能与功能柯里工作... 看看这里:http://www.codecommit.com/blog/scala/function-currying-in-scala 那么你可以用该功能在某些时候的咖喱功能(Function.curried)和简单的东西在参数传递给打电话叫它再

+0

这很有趣,但它使我在编译时指定arg类型。另外我如何使用它来调用多个这样的功能? – 2012-04-17 08:22:54

2

我想你想要的东西,如:

def funcWithArgs(args: String*) = args foreach println 
def callAnyFuncWithArgs[A, B] 
    (args: A*)(f: (A*) => B) = f(args: _*) 

,然后调用funcWithArgs为部分应用功能:

callAnyFuncWithArgs("bingo")(funcWithArgs _) 
+1

你可以将返回类型设置为'B'。 – incrop 2012-04-17 10:20:29

+1

+1,好点,但实际上,我们可以删除返回类型,因为B返回类型将由编译器推断(我们正在调用一个本身返回B的函数);当然这只适用于调用f()是要执行的唯一操作;否则,是的,OP应该强制执行B返回类型 – virtualeyes 2012-04-17 11:20:47

+0

谢谢virtualeyes,我已经改变了上面的代码,但正如Daneiel指出的,我仍然需要编写一堆样板代码。关于退货类型的好处! – 2012-04-17 16:01:12