Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在scala中编写函数isFunction?_Scala - Fatal编程技术网

如何在scala中编写函数isFunction?

如何在scala中编写函数isFunction?,scala,Scala,如何在scala中编写isFunction函数,以便: def isFunction(x:Any) = /* SomeCode */ println(isFunction(isFunction _)) //true println(isFunction("not a function")) //false 很难看,但它能起作用: def isFunction(x:Any) = x match { case _: Function0[_] => true case _: Func

如何在scala中编写isFunction函数,以便:

def isFunction(x:Any) = /* SomeCode */

println(isFunction(isFunction _)) //true
println(isFunction("not a function")) //false

很难看,但它能起作用:

def isFunction(x:Any) = x match {
  case _: Function0[_] => true
  case _: Function1[_, _] => true
  case _: Function2[_, _, _] => true
  ...
  case _: Function22[...] => true
  case _: PartialFunction[_, _] => true
  case _ => false
}

很难看,但它能起作用:

def isFunction(x:Any) = x match {
  case _: Function0[_] => true
  case _: Function1[_, _] => true
  case _: Function2[_, _, _] => true
  ...
  case _: Function22[...] => true
  case _: PartialFunction[_, _] => true
  case _ => false
}

在scala中,您可以仅将函数视为具有公共
apply
方法的对象。我不熟悉新的scala 2.10反射api,但您可以始终使用传统的java方式:

def isFunction(x:Any) = x.getClass.getMethods.map(_.getName).exists{name => 
  name == "apply" || name.startsWith("apply$")
}

val set = Set(1, 2)
val str = "abc"
val func = { _:Int=> 1 }
val map = Map(1 -> 2)
val tuple = 1->2
val obj = new { def apply = 1 }
val obj2 = new { private def apply = 2 } 

assert(isFunction(set))
assert(!isFunction(str))
assert(isFunction(func))
assert(isFunction(map))
assert(!isFunction(tuple))
assert(isFunction(obj))
assert(!isFunction(obj2))

在scala中,您可以仅将函数视为具有公共
apply
方法的对象。我不熟悉新的scala 2.10反射api,但您可以始终使用传统的java方式:

def isFunction(x:Any) = x.getClass.getMethods.map(_.getName).exists{name => 
  name == "apply" || name.startsWith("apply$")
}

val set = Set(1, 2)
val str = "abc"
val func = { _:Int=> 1 }
val map = Map(1 -> 2)
val tuple = 1->2
val obj = new { def apply = 1 }
val obj2 = new { private def apply = 2 } 

assert(isFunction(set))
assert(!isFunction(str))
assert(isFunction(func))
assert(isFunction(map))
assert(!isFunction(tuple))
assert(isFunction(obj))
assert(!isFunction(obj2))

我不是你的解决方案的特别粉丝,我同意丹尼尔·索布拉尔的评论。如果我必须实现它,我会以类型安全的方式,通过隐式转换来实现

trait IsFunctionable {
  def isFunction : Boolean
}

object IsFunctionable {

  object IsFunction extends IsFunctionable {
    def isFunction = true
  }

  object IsNotFunction extends IsFunctionable {
    def isFunction = false
  }

  implicit def function0ToIsFunctionable[A<:Function0[_]](a:A):IsFunctionable = IsFunction
  implicit def function1ToIsFunctionable[A<:Function1[_,_]](a:A):IsFunctionable = IsFunction
  implicit def function2ToIsFunctionable[A<:Function2[_,_,_]](a:A):IsFunctionable = IsFunction
  // and so on

  implicit def anyToIsFunctionable[A](a:A):IsFunctionable = IsNotFunction
}
trait是可操作的{
def isFunction:Boolean
}
对象是可函数的{
对象IsFunction扩展了IsFunctionable{
def isFunction=true
}
对象IsNotFunction扩展IsFunctionable{
def isFunction=false
}
隐式def function0ToIsFunctionable[A Int=*2
答:Int=>Int=
scala>valb:(Int,Int)=>Int=()
b:(Int,Int)=>Int=
scala>a(3)
res0:Int=6
scala>b(2,4)
res3:Int=8
scala>a.isf函数
res4:Boolean=true
scala>b.isFunction
res5:Boolean=true
scala>“Hello”。isFunction
res6:Boolean=false

我不是您的解决方案的特别粉丝,我同意Daniel Sobral的评论。如果我必须实现它,我会通过隐式转换以类型安全的方式实现

trait IsFunctionable {
  def isFunction : Boolean
}

object IsFunctionable {

  object IsFunction extends IsFunctionable {
    def isFunction = true
  }

  object IsNotFunction extends IsFunctionable {
    def isFunction = false
  }

  implicit def function0ToIsFunctionable[A<:Function0[_]](a:A):IsFunctionable = IsFunction
  implicit def function1ToIsFunctionable[A<:Function1[_,_]](a:A):IsFunctionable = IsFunction
  implicit def function2ToIsFunctionable[A<:Function2[_,_,_]](a:A):IsFunctionable = IsFunction
  // and so on

  implicit def anyToIsFunctionable[A](a:A):IsFunctionable = IsNotFunction
}
trait是可操作的{
def isFunction:Boolean
}
对象是可函数的{
对象IsFunction扩展了IsFunctionable{
def isFunction=true
}
对象IsNotFunction扩展IsFunctionable{
def isFunction=false
}
隐式def function0ToIsFunctionable[A Int=*2
答:Int=>Int=
scala>valb:(Int,Int)=>Int=()
b:(Int,Int)=>Int=
scala>a(3)
res0:Int=6
scala>b(2,4)
res3:Int=8
scala>a.isf函数
res4:Boolean=true
scala>b.isFunction
res5:Boolean=true
scala>“Hello”。isFunction
res6:Boolean=false

顺便说一句,因为你也问过和:你有弱类型的背景吗,例如Python?一个更好的问题是,我如何避免使用以
Any
为参数的方法,并描述你正在尝试做什么。如果你认为你需要这样的事情,通常你在做错事。就像旧的OO ada一样ge说:告诉,不要问。让对象担心它是什么以及它是如何工作的,正如Luigi所说,不要使用
任何
。我确实知道它不是“好的惯用scala”,但我正在重写scala中“小Schemer”的例子,在scheme(类似于书)和scala(类似于好的代码)“惯用语”中.Btw,既然你也问了和:你有弱类型的背景吗,例如Python?一个更好的问题是,我如何避免使用将
Any
作为参数的方法,并描述你正在尝试做什么。如果你认为你需要这样的事情,通常你在做错事。正如古老的OO格言所说的那样:说,不要问。让对象担心它是什么以及它是如何做的,正如Luigi所说,不要使用
任何
。我确实知道它不是“好的惯用scala”,但我正在重写scala中“小Schemer”的例子,在scheme(类似于书)和scala(类似于好的代码)“惯用语”中。谢谢@pedrofurla。我还添加了
PartialFunction
。谢谢@pedrofurla。我还添加了
PartialFunction
。函数是对象,是的。但不是所有具有apply方法的对象都是函数。我们通常不关心对象的定义签名是什么,而是关心对象的行为。Scala本身接受具有
在模式匹配中将
方法作为
提取器
不应用。它还具有“视图边界”,这正是我所说的“视图函数为”的原因。此解决方案在概念上可能不正确(事实上,这取决于您所称的
函数
)但它确实可以处理超过22个参数的情况。函数是对象,是的。但并非所有使用apply方法的对象都是函数。我们通常不关心对象的定义签名是什么,而是关心对象的行为。Scala本身将具有
unapply
方法的对象作为
提取器。它也有“视图边界”,这正是我说“视图函数为”的原因。此解决方案在概念上可能不正确(事实上,这取决于您所称的
函数
),但它确实能处理具有22个以上参数的情况。