我正在努力解决这个问题:我需要一个能够执行任何功能的函数 fun类型(Any *):Boolean作为参数,计算函数并返回true或 是的,取决于功能评估的成功。
基本上,我需要的是一个函数类型,它允许任何数字和任何类型的参数,但函数必须返回布尔值。
这将允许我编写如下函数:
def checkLenght(str : String, length : Int) : Boolean ={
if (str.lenght == length)}
或
def ceckAB(a : Int, b : Int) : Boolean = {
if(a < b && a >= 23 && b < 42) }
所以,例如
eval(checkLenght(abc, 3)) //returns true
eval(ceckAB(4,1)) // returns false
我想,功能类型为:
type CheckFunction = (Any*) => Boolean
可能会成功,但我很难编写通用的eval函数。
有什么建议吗?
谢谢
解决方案:
该功能需要 1)返回类型布尔的另一个函数:“(func:=&gt; Boolean)” 2)返回类型Boolean“:Boolean” 3)返回传递的函数参数的值:“= func”
这个功能总是:
def eval(func : => Boolean) : Boolean = func
令我惊讶的是,Scala中的简单事物是多么简单。
正如评论所指出的,这是一个相当不寻常的功能,没有明显的 感。只是关于潜在原因的一句话。
动机:
关于潜在动机存在很多疑问,所以这里简短 总结为什么需要这样的功能。
基本上,有两个原因。
第一个是关于将故障处理从功能本身移开 进入处理函数。这保留了检查功能的纯度,甚至允许 重复使用通用支票。
其次,关键是“可插拔故障处理”。这意味着,仅限eval函数 告知是否发生了故障。如果发生故障,则通过接口调用处理程序。可以根据需要使用配置文件交换处理程序的实现。
为什么呢?
交换配置文件意味着,我像往常一样编码我的支票和功能,但通过切换 配置文件,我切换处理程序,这意味着我可以选择全程,控制台打印输出,电子邮件警报,SNMP通知,推送消息...你的名字。为此,我需要将检查功能与其评估和处理分离。这就是这种看起来很奇怪的eval函数的动机。
为了完整起见,我已经实现了所有这些东西,但是我面临的只是处理琐碎的检查的限制,即检查(布尔*)这是整洁的但通常我更愿意写一个函数来做更多复杂的检查。
通过返回传递函数的值来定义函数:
def eval(func : => Boolean) : Boolean = {func}
答案 0 :(得分:2)
我不能说我真的理解你想要做你想做的事情的动机,但我想这不是重点。也许eval
函数会在调用提供的函数之前检查某些内容,并且在给定某些条件的情况下不会调用其他函数(如快速失败)。也许您在调用函数后进行一些后期检查,并根据其他内容更改结果。无论哪种方式,我想你可以通过以下代码完成类似于你想要的东西:
def main(args: Array[String]) {
val str = "hello world"
println(eval(checkLength(str, 3)))
println(eval(intsEqual(1,1)))
}
def eval(func: => Boolean):Boolean = {
//Do whetever you want before invoking func, maybe
//not even invoke it if some other condition is present
val fres = func
//Maybe change something here before returning based on post conditions
fres
}
def checkLength(s:String, len:Int) = s.length() == len
def intsEqual(a:Int, b:Int) = a == b
如果你真的希望eval
函数能够支持任何带有任何类型args的函数并返回Boolean
,那么使用这样的by-name函数,然后利用闭包在by-name函数中,将任何参数传递给你想要调用的任何实际函数。证明这一点的更好方法如下:
def checkMyString(str:String, len:Int) = {
eval(str.length == len)
}
可能很难看到除非str.length == len
决定调用它,直到将其展开为真实形式,否则不会调用eval
检查:
def checkMyString(str:String, len:Int) = {
def check = {
str.length == len
}
eval(check)
}
此处,由于关闭,嵌套函数check
可以访问str
和len
,这样您就可以绕过eval
必须能够满足的要求使用任何返回Boolean
的参数来调用函数。
这只是解决问题的一种方法,根据您的需要,它甚至可能不合适,但我只是想把它扔出去。
答案 1 :(得分:1)
如果你的输入函数只有2个参数,就像你的两个例子一样,你可以编写一个半泛型函数take take all with two arguments of any type:
def eval[A,B](func: (A,B) => Boolean, arg1: A, arg2: B) = {
func(arg1, arg2)
}
def checkLength(str: String, length: Int) : Boolean = {
str.length == length
}
eval(checkLength, "ham", 4)
res0: Boolean = false
但是如果你想支持具有更多参数的函数,你必须为三个参数,四个参数等编写一个eval
函数。
也许有更好的方法可以处理所有情况?