【问题标题】:capture types of varargs parameters捕获可变参数参数的类型
【发布时间】:2010-05-05 15:08:57
【问题描述】:

我想定义一个接受可变参数的方法,这样即使在 null 的情况下我也能得到调用它的类型。

def foo(args: Any*) = ....

val s: String = null

foo(1, s) // i'd like to be able to tell in foo that args(0) is Int, args(1) is String

【问题讨论】:

标签: scala


【解决方案1】:

如果您使用Any 作为参数类型,您将无法静态确定参数的类型。您将不得不使用instanceof 或模式匹配:

def foo(args: Any*) = for (a <- args) a match {
  case i: Int =>
  case s: String =>
  case _ =>
}

不幸的是,这无法处理空值。

如果你想要静态类型,你将不得不使用重载:

def foo[A](arg1: A)
def foo[A, B](arg1: A, arg2: B)
def foo[A, B, C](arg1: A, arg2: B, arg3: C)
...

【讨论】:

  • 或者使用支持类型化 'varargs' 的语言,例如 TypedScheme :)
【解决方案2】:

就最初的问题而言,我很确定这是不可能的。

如果不确切知道您想要实现什么(即为什么它必须是任意类型的可变长度列表),就很难提供替代方案。但是,当我阅读可能适合您的问题时,我想到了两件事:Default argument values 结合命名参数(需要 Scala 2.8+)和HList 数据类型(不太可能) .

【讨论】:

    【解决方案3】:

    因为您使用Any 作为类型,所以您无法获取参数的类型。 Any 类型没有 getClass 方法(它甚至根本不是引用类)。请参阅http://www.scala-lang.org/node/128 了解更多信息。

    你可以试试这个:

    def foo(args: Any*) = args.map { arg => {
      arg match {
        case reference:AnyRef => reference.getClass.toString
        case null => "null"
    }}}
    
    val s: String = null
    
    val result = foo("a", 1, 'c', 3.14, s, new Object, List(1), null)
    
    result.foreach(println)
    

    这个输出:

    class java.lang.String
    class java.lang.Integer
    class java.lang.Character
    class java.lang.Double
    null
    class java.lang.Object
    class scala.collection.immutable.$colon$colon
    null
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多