Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.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 带有类标记/类型标记的模式匹配函数签名_Scala_Scala 2.10 - Fatal编程技术网

Scala 带有类标记/类型标记的模式匹配函数签名

Scala 带有类标记/类型标记的模式匹配函数签名,scala,scala-2.10,Scala,Scala 2.10,我有一个方法,可以为不同的函数类探索不同的参数值。之前,我做了一些非类型安全运行时检查,在擦除之后,重要的是我使用的是Function2而不是Function3。为了安全起见,我尝试使用ClassTags/TypeTags,但我仍在努力寻找一个好的解决方案。我最初的参考点是 tksfz对以下问题的答复: 然而,我发现给出的代码片段不起作用,并且两种情况都匹配一个字符串列表——答案可能与scala的不同版本有关(我使用的是2.10.3) 我发现了另一个例子,其中有人给出了一个使用TypeTags

我有一个方法,可以为不同的函数类探索不同的参数值。之前,我做了一些非类型安全运行时检查,在擦除之后,重要的是我使用的是Function2而不是Function3。为了安全起见,我尝试使用ClassTags/TypeTags,但我仍在努力寻找一个好的解决方案。我最初的参考点是 tksfz对以下问题的答复:

然而,我发现给出的代码片段不起作用,并且两种情况都匹配一个字符串列表——答案可能与scala的不同版本有关(我使用的是2.10.3)

我发现了另一个例子,其中有人给出了一个使用TypeTags的代码片段(我仍然不清楚类型标记类型之间的区别;我很高兴在这一点上有一个RTFM响应,只要它附带一个指向好的m到FR的链接)

编辑:我前面的示例没有应用函数,因此匹配中产生警告的部分毫无意义(正如第一位回答者所指出的)。我已经更新了示例,使其更能代表我的实际问题

package misc
import reflect.runtime.universe._

object CTDemo {

  def main(args: Array[String]) = {
    val f0v: Function2[Int, Double, String] = f0(_, _)
    val f1v: Function2[Int, (Double, Double), String] = f1(_, _)
    println(matchFunc(f0v))
    println(matchFunc(f1v))
  }

  def f0(i: Int, p: Double) = {
    s"output on $p doesn't matter"
  }

  def f1(i: Int, p: (Double, Double)) = {
    s"output on $p doesn't matter"
  }

  def matchFunc[I: TypeTag, A: TypeTag, O: TypeTag](predFunc: Function2[I, A, O]) = {
    predFunc match {
      case fs: Function2[Int, Double, String] if(typeOf[A] <:< typeOf[Double]) => {
        "Single-arg, result is: " + fs(1,2.0)
      }
      case ds: Function2[Int, (Double, Double), String] if(typeOf[A] <:< typeOf[(Double,Double)])  => {
        "Double-arg, result is: " + ds(1,(2.0,3.0))
      }
    }
  }
}
包杂项
导入reflect.runtime.universe_
对象CTDemo{
def main(参数:数组[字符串])={
val f0v:Function2[Int,Double,String]=f0(0,0)
val f1v:Function2[Int,(Double,Double),String]=f1(u,u)
println(matchFunc(f0v))
println(matchFunc(f1v))
}
def f0(i:Int,p:Double)={
s“p美元的产出无关紧要”
}
DEFF1(i:Int,p:(双精度,双精度))={
s“p美元的产出无关紧要”
}
def matchFunc[I:TypeTag,A:TypeTag,O:TypeTag](predFunc:Function2[I,A,O])={
预函数匹配{
案例fs:Function2[Int,Double,String]if(typeOf[A]{
“单参数,结果为:”+fs(1,2.0)
}
案例ds:Function2[Int,(Double,Double),String]if(typeOf[A]{
“双参数,结果是:”+ds(1,(2.0,3.0))
}
}
}
}

这种情况是可行的,但它仍然会引发编译器警告。是否有一种简洁的、无警告的、线程安全的方法来检查函数的类型签名?如果有帮助的话,我愿意升级到scala 2.11。

您的匹配项不起任何作用,所以

  def matchFunc[I: TypeTag, A: TypeTag, O: TypeTag](predFunc: Function2[I, A, O]) = {
      if (typeOf[A] <:< typeOf[Double]) {
        "Single-arg"
      } else if (typeOf[A] <:< typeOf[(Double,Double)]) {
        "Double-arg"
      }
  }
def matchFunc[I:TypeTag,A:TypeTag,O:TypeTag](predFunc:Function2[I,A,O])={
if(typeOf[A]“I”}
g:[A](as:List[A])(隐式证据$1:scala.reflect.ClassTag[A])字符串
scala>g(列表(3))
res4:String=I
scala>g(列表(3.0))
scala.MatchError:List(3.0)(属于类scala.collection.immutable.$colon$colon)
at.g(:7)
…33删去
也就是说,作为一种荣耀(尽管方便)的替代品


在Scala中,它是RTFS,其中s=spec或SIP。

谢谢你的回答。我应该使用一个更好的例子,因为在我的实际代码中,匹配的函数实际上正在应用。我编辑了我的代码块以反映这一点。
  def matchFunc[I: TypeTag, A: TypeTag, O: TypeTag](predFunc: Function2[I, A, O]) = {
      if (typeOf[A] <:< typeOf[Double]) {
        "Single-arg"
      } else if (typeOf[A] <:< typeOf[(Double,Double)]) {
        "Double-arg"
      }
  }
scala> def g[A: reflect.ClassTag](as: List[A]) = as match { case List(_: Int) => "I" }
g: [A](as: List[A])(implicit evidence$1: scala.reflect.ClassTag[A])String

scala> g(List(3))
res4: String = I

scala> g(List(3.0))
scala.MatchError: List(3.0) (of class scala.collection.immutable.$colon$colon)
  at .g(<console>:7)
  ... 33 elided