在 Scala 中将 Array[Any] 转换为 Varargs

Casting Array[Any] to Varargs in Scala

我有一个方法 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 分配给传递给 fooSeq 的第一个元素。有什么方法可以定义 bar 以便它正确调用 foo?

找到答案了。将 bar 定义为

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

成功了。

你不应该有那个问题,那个代码应该可以正常工作并且对我来说工作正常。

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 参数,这些参数也会在您的函数中作为序列接收。

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

_*是特殊的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