Scala通用数组元素

时间:2017-09-29 23:06:47

标签: arrays scala generics

我正在尝试编写一个函数来计算T类型元素数组中元素的数量,这些元素通过了T =>布尔类型的测试。

到目前为止我所拥有的是:

     def countPass[T](elem: Array[T]) = {
        var count = 0
        for(x <- elem) 
            x match { 
                case x: T => count += 1
            }
        count
    }

    //TEST
    println(countPass[Boolean](Array(true, 52, "test")))

我遇到了一些错误,第一个错误是:

combinators.scala:45: warning: abstract type pattern T is unchecked since
it is eliminated by erasure
                        case x: T => count += 1
                                ^

下一个错误是:

combinators.scala:54: error: type mismatch;
 found   : Int(52)
 required: Boolean
    println(countPass[Boolean](Array(true, 52, "test")))
                                           ^
combinators.scala:54: error: type mismatch;
 found   : String("test")
 required: Boolean
    println(countPass[Boolean](Array(true, 52, "test")))
                                               ^

我不确定第一个错误发生了什么,但是第二个错误它会在不是布尔值时抛出异常。我不希望发生这种情况,因为我只是计算数组中T类型元素的数量。

问题:我应该如何重构代码来修复这两个错误?

3 个答案:

答案 0 :(得分:7)

诀窍是使用ClassTag。完成请求的更好方法如下:

import scala.reflect.ClassTag

object Main extends App {

  val array: Array[Any] = Array("string1", "string2", "string3", true, false, 13)

  def countPass[Other: ClassTag](array: Array[Any]): Int = {
    array.collect { case x: Other => x }.length
  }

  println(s"countPass String = ${countPass[String](array)}")
  println(s"countPass Boolean = ${countPass[Boolean](array)}")
  println(s"countPass Int = ${countPass[Int](array)}")
}

您可以阅读this了解有关ClassTagTypeTag

的更多信息

答案 1 :(得分:0)

所以我发现了一种有效的方法,但不完全是我想要的方式。

     def countPass[T](elem: Array[T]) = {
        var count = 0
        for(x <- elem) 
            x match { 
                case _: Boolean => count += 1
                case _ => None
            }
        count
    }

    //TEST
    println(countPass[Any](Array(true, 5, "test", false, false)))

问题是我需要将Any传递给数组,因为我有不同的类型。另外,我需要稍微改变一下我的情况并添加默认情况。

这很有效,但我想要更像这样的东西。由于上面指定的错误

,这不起作用
    def countPass[T](elem: Array[Any]) = {
        var count = 0
        for(x <- elem) 
            x match { 
                case _: T => count += 1   //Here is the error
                case _ => None
            }
        count
    }

    //TEST
    println(countPass[Boolean](Array(true, 5, "test", false, false)))

出于某种原因,我无法做_:T作为我的情况或我收到此错误:

combinators.scala:44: warning: abstract type pattern T is unchecked since 
it is eliminated by erasure
                case _: T => count += 1

答案 2 :(得分:0)

您可以直接使用方法计数

def countPass[T: ClassTag](elem: Array[Any]): Int = elem.count{
    case _ : T => true
    case _ => false
}