问题
I define the following variable x
val x = Array((3,2), (4,5))
Its type is Array[(Int, Int)]
When I do the following:
x.map((a: Int, b: Int) => "(" + a + ", " + b + ")")
I get the following error:
console:28: error: type mismatch;
found : (Int, Int) => String
required: ((Int, Int)) => ?
x.map((a: Int, b: Int) => "(" + a + ", " + b + ")")
Why does it expect the type of the first element to be ((Int, Int))
?
回答1:
(Int, Int) => ...
is the type of a function with two arguments, both Int
(and that's what (a: Int, b: Int) => ...
will always give).
((Int, Int)) => ...
is the type of a function with one (Int, Int)
argument. map
on Array
needs a function with one argument and for Array[(Int, Int)]
the type of this argument must be (Int, Int)
.
So you need to write either
x.map(pair => "(" + pair._1 + ", " + pair._2 + ")")
where pair
has type (Int, Int)
, or
x.map { case (a, b) => "(" + a + ", " + b + ")" }
(using pattern-matching). Note that in this case braces are required.
回答2:
You have created an array of Tuple. Scala tuple combines a fixed number of items together so that they can be passed around as a whole. Unlike an array or list, a tuple can hold objects with different types but they are also immutable.
To access the value of tuple, Scala provides._1
,._2
to access the value of a tuple.
For example
scala> val tuple = (2,4)
tuple: (Int, Int) = (2,4)
scala> tuple._1
res11: Int = 2
scala> tuple._2
res12: Int = 4
If you have more than two values in the tuple, ._3 will use to get the third value of tuple.
And similarly, you have created Arrays of tuple2.
scala> val arr = Array((1,1), (2,4), (3,9))
arr: Array[(Int, Int)] = Array((1,1), (2,4), (3,9))
scala> arr.map(tuple => "(" + tuple._1 + "," + tuple._2 + ")" )
res13: Array[String] = Array((1,1), (2,4), (3,9))
Another way you can use pattern matching to get the value.
scala> arr.map{
| case (a: Int, b: Int) => "(" + a + "," + b + ")" }
res17: Array[String] = Array((1,1), (2,4), (3,9))
回答3:
It's a little unintuitive quirk of Scala that map(whatever=>...)
the whatever is actually one thing - of the type the Seq you are mapping over, which you can/need to deconstruct later. Fortunately, as others noted, you can use pattern matching and for that to work you need to replace the brackets with curly brackets and add the case keyword so map {case (a,b) => }
etc.
回答4:
The reason for the error is already given by Alexey Romanov. and it can also be done like this if you want using pattern matching:
x.map(v=>{val (a,b)=v;"(" + a + ", " + b + ")"})
In Scala REPL:
scala> val x = Array((3,2), (4,5))
x: Array[(Int, Int)] = Array((3,2), (4,5))
scala> x.map(v=>{val (a,b)=v;"(" + a + ", " + b + ")"})
res2: Array[String] = Array((3, 2), (4, 5))
来源:https://stackoverflow.com/questions/51227041/scala-lambda-function-with-map-function