将数组[任意]转换为Scala中的Varargs

时间:2015-03-04 08:59:04

标签: scala variadic-functions

我的方法foo需要Seq[Any]。例如:

def foo(a:Seq[Any]) = println(a.size)

foo(Seq("hi", 1, true)) // prints 3

我希望每次都避免写Seq。所以我想定义一个方法bar,我可以称之为:

bar("hi", 1, true) 

与调用foo(Seq("hi", 1, true))具有相同的效果。

定义以下内容:

def bar(b:Any *) = foo(b)

并将其用作:

bar("hi", 1, true) // prints 1

无法按预期工作。它会将b分配给传递给Seq的{​​{1}}的第一个元素。我有什么方法可以定义foo,以便正确调用bar

2 个答案:

答案 0 :(得分:1)

您不应该遇到这个问题,该代码应该可以正常工作并且对我来说很好。

scala> def foo(a:Seq[Any]) = println(a.size)
foo: (a: Seq[Any])Unit

scala> def bar( b: Any* ) = foo( b )
bar: (b: Any*)Unit

scala> bar( "hi" , 34, 23 )
3

scala> bar( "hi" , 34, true )
3

发生这种情况的原因是因为*-paramters在函数体中被隐式接收为Seq。这意味着即使您传递多个varargs参数,这些参数也会在您的函数中作为序列接收。

您可以使用_*注释再次将一系列事物转换为多个varargs参数。

_*是特殊的annotation,只能在函数的arguments*-parameter中使用。它会将sequence作为*-parameter传递。

以下示例将清除事情。

scala> val l = List( 4, 5, 6, 7, 3, 6, 3 )
l: List[Int] = List(4, 5, 6, 7, 3, 6, 3)    

scala> def pp( ints: Int* ) = println( ints )
pp: (ints: Int*)Unit

// All Int* are implicitly received as a Seq[ Int ]
// Hence, ints will be a Seq[ Int ] in function body
// ( WrappedArray[ int ] in this case ) in function body.
scala> pp( 4, 5, 6 )
WrappedArray( 4, 5, 6 )

// Received as List[ Int ] in this case
scala> pp( l: _* )
List(4, 5, 6, 7, 3, 6, 3)

scala> def a( ints: Int* ) = ints.sum
a: (ints: Int*)Int

// passing a list wont work
scala> a( l )
<console>:11: error: type mismatch;
  found   : List[Int]
  required: Int
           a( l )
              ^

// list passed as multiple parameters
scala> a( l: _* )
res8: Int = 34

答案 1 :(得分:0)

找到答案。将bar定义为

def bar(b:Any *) = foo(b.toSeq)

诀窍。